class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
如何确定用于值a的类型参数的子类的类型?
答案 0 :(得分:3)
你不能因为类型删除。但是,我认为你这样做的尝试是由于误解而产生的。
在您的计划中,有一个引用a
,此引用的类型为ClassWithTypeParameter[S]
。那。是。所有。编译器可以知道该引用可以做什么。这些类型纯粹用于编译器。事实上,在运行时,a
被分配给ClassWithTypeParameter[A]
的值是无关紧要的。
将用于某种近似(受删除限制)的一种可能方法是使用清单(在2.10中称为其他内容):
class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }
然后你可以致电erasure
,这会让你java.lang.Class
回来。正如我所说,这是有限的。 类与类型不同,并且无法区分,例如ClassWithTypeParameter[List[Int]]
与ClassWithTypeParameter[List[Double]]
答案 1 :(得分:2)
以下是一个坏主意(与大多数反射的使用一样),但它有效:
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
的{{1}}和paramSupertypeOf
撰写类似的Manifest
和<:<
方法。
在Scala 2.10(里程碑4或更高版本)中,有a much more flexible way来获取类型:
>:>
现在你可以编写像class ClassWithTypeParameter[+T: TypeTag] {
def paramType = reflect.runtime.universe.typeTag[T].tpe
}
这样的东西来获得直接的超类型等等。