class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
如何确定用于类型参数值为a的子类的类型?如何确定Scala中的类型参数的子类型?
class S
class A extends S
class B extends S
class ClassWithTypeParameter[+T]
val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
如何确定用于类型参数值为a的子类的类型?如何确定Scala中的类型参数的子类型?
你不能因为类型擦除。但是,我认为你的这种尝试是由误解形成的。
在程序中,存在一个参考,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]]
下面是一个糟糕的主意(如反射的大多数用途),但它的工作原理:
class ClassWithTypeParameter[+T: Manifest] {
def paramIs[V: Manifest] = manifest[T] == manifest[V]
}
这给了我们:
scala> val a: ClassWithTypeParameter[S] = new ClassWithTypeParameter[A]
a: ClassWithTypeParameter[S] = [email protected]
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]] = [email protected]
scala> i.paramIs[List[Int]]
res3: Boolean = true
scala> i.paramIs[List[Double]]
res4: Boolean = false
你可以通过编写类似paramSubtypeOf
和paramSupertypeOf
方法Manifest
的<:<
和>:>
。
在斯卡拉2.10(里程碑4或更高版本)有a much more flexible way拿到类型:
class ClassWithTypeParameter[+T: TypeTag] {
def paramType = reflect.runtime.universe.typeTag[T].tpe
}
现在你可以写像a.paramType.parents
事情让眼前的超类型等
感谢您的额外信息! –
但它是可能的使用清单来区分'CWTP [List [Int]]和'CWTP [List [Double]]' - 如果你删除了,就不要这样做。 –
@oxbow_lakes谢谢你的解释,这对我有很大的帮助。 –