2012-06-25 89 views

回答

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]]

+0

但它是可能的使用清单来区分'CWTP [List [Int]]和'CWTP [List [Double]]' - 如果你删除了,就不要这样做。 –

+0

@oxbow_lakes谢谢你的解释,这对我有很大的帮助。 –

2

下面是一个糟糕的主意(如反射的大多数用途),但它的工作原理:

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 

你可以通过编写类似paramSubtypeOfparamSupertypeOf方法Manifest<:<>:>

在斯卡拉2.10(里程碑4或更高版本)有a much more flexible way拿到类型:

class ClassWithTypeParameter[+T: TypeTag] { 
    def paramType = reflect.runtime.universe.typeTag[T].tpe 
} 

现在你可以写像a.paramType.parents事情让眼前的超类型等

+0

感谢您的额外信息! –