class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
値 a の型パラメーターに使用されるサブクラスの型をどのように判断できますか?
class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
値 a の型パラメーターに使用されるサブクラスの型をどのように判断できますか?
タイプ eraserのため、できません。ただし、これを行うあなたの試みは誤解から形成されていると私は主張します。
プログラムには 1 つの参照がa
あり、この参照の型は ですClassWithTypeParameter[S]
。それか。は。全て。コンパイラは、この参照で何ができるかを知ることができます。型は純粋にコンパイラ用です。実行時にa
が である値に割り当てられたという事実ClassWithTypeParameter[A]
は無関係です。
これをある程度近似する(消去によって制限される) 方法の 1 つは、マニフェストを使用することです (2.10 では別のものと呼ばれます)。
class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }
次に、erasure
どちらがあなたを取り戻すかを呼び出すことができますjava.lang.Class
。何度も言いますが、これは限定的です。クラスは型と同じものではなく、たとえば、型と区別する方法はありませClassWithTypeParameter[List[Int]]
ん。ClassWithTypeParameter[List[Double]]
以下は (リフレクションのほとんどの使用法と同様に) 悪い考えですが、機能します:
class ClassWithTypeParameter[+T: Manifest] {
def paramIs[V: Manifest] = manifest[T] == manifest[V]
}
これにより、次のことがわかります。
scala> val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
a: ClassWithTypeParameter[S] = ClassWithTypeParameter@6493c09c
scala> a.paramIs[A]
res0: Boolean = true
scala> a.paramIs[S]
res1: Boolean = false
scala> a.paramIs[B]
res2: Boolean = false
と:
scala> val i = new ClassWithTypeParameter[List[Int]]
i: ClassWithTypeParameter[List[Int]] = ClassWithTypeParameter@260702ee
scala> i.paramIs[List[Int]]
res3: Boolean = true
scala> i.paramIs[List[Double]]
res4: Boolean = false
とを使用して同様のparamSubtypeOf
とparamSupertypeOf
メソッドを書くことができます。Manifest
<:<
>:>
Scala 2.10 (Milestone 4 以降) では、より柔軟に型を取得する方法があります。
class ClassWithTypeParameter[+T: TypeTag] {
def paramType = reflect.runtime.universe.typeTag[T].tpe
}
a.paramType.parents
これで、すぐにスーパータイプを取得するようなものを書くことができます。