私は、俳優のreceive
メソッドのようなタイプを消去するインターフェイスを通して関数を渡す必要があります。だから私は消去された型パラメータを格納し、引数をキャストするために使用したいと思います。関数の型を削除するときの関数の使い方は?
val c0 = a0.action(source)
val c1 = a1.action(c0)
明らかに失敗します:
class Store[R,T](val action : R => T)(implicit i : TypeTag[R], o : TypeTag[T]) {
val in : Type = i.tpe
val out : Type = o.tpe
}
object Store {
type Any = Store[_,_]
def apply[R,T](action : R => T)(implicit i : TypeTag[R], o : TypeTag[T]) : Store[R,T] = new Store(action)
}
final case class Box[T](unbox : T)
def getType[T](x : T)(implicit t : TypeTag[T]) : Type = t.tpe
val source = Box("test")
val x = Store[Box[String], Box[Int]](s => Box(s.unbox.length))
val y = Store[Box[Int], Box[Boolean]](i => Box(i.unbox % 3 == 0))
val all : List[Store.Any] = List(x,y)
val a0 = all(0)
val a1 = all(1)
私はそのようなチェーン保存されたアクションをしたい
私はすべての種類は、実行時に一致していることを確認できたerror: type mismatch;
found : source.type (with underlying type Box[String])
required: _$1
val c0 = a0.action(source)
^
one error found
:
assert(getType(source) <:< a0.in)
assert(a0.out <:< a1.in)
しかし、どうすれば実際の引数を適切な型に変換しますか? asInstanceOf
には実行時のリフレクションではなく、コンパイル時の型が必要です。他にどんなトリックがありますか?それを行うには
'ClassTag [T]'は、 'T'型を保つ必要があります。 >型が常に< - それは問題ではないと仮定するか、上に示したように常に型を宣言できます。 >型のクラス<しかし、すべての型が失われたときに実行時には役に立たない。 'Any'型を受け入れるインタフェースにオブジェクトを渡す必要がある場合は、ランタイムパターンのマッチングだけが可能です。 – ayvango
ある時点で、あなたは' T 'の型を知っています - これは 'ClassTag'とオブジェクトにアクセスする前にオブジェクトを実際に制御できない場合や、型がすでに失われている場合を除き、それを忘れるコード部分に渡してください。 タイプ「T」を保持するために、必ずしも必要ではありません。ある時点で、存在するタイプの使用を開始するかもしれません。それで、Tは 'SomeTHandler [T](値:T)(暗黙のタグ:ClassTag [T])'クラスの内部で知ることができますが、インターフェースレベルでは 'SomeHanlderT [_]'と呼ばれます。 –
そして、タイプがすでに消去されているときに 'SomeHandlerT [_]'が 'Option [T]'を返すとはどうでしょうか? – ayvango