如何在Scala中确定类型参数的子类型?

如何在Scala中确定类型参数的子类型?,scala,type-parameter,Scala,Type Parameter,如何确定用于值a的类型参数的子类的类型 由于类型擦除,您无法执行。然而,我想说的是,你这样做是因为误解 类型系统的要点是,编译器可以更有力地推理程序的正确性 在静态类型系统中,每个引用都有一个不能更改的类型 在您的程序中,有一个引用,a,该引用的类型是ClassWithTypeParameter[S]。那个是全部的编译器可以知道使用此引用可以做什么。这些类型纯粹用于编译器。在运行时,a被分配给ClassWithTypeParameter[a]的值这一事实是不相关的 对某种近似值(受擦除限制

如何确定用于值a的类型参数的子类的类型

由于类型擦除,您无法执行。然而,我想说的是,你这样做是因为误解

  • 类型系统的要点是,编译器可以更有力地推理程序的正确性
  • 在静态类型系统中,每个引用都有一个不能更改的类型
在您的程序中,有一个引用,
a
,该引用的类型是
ClassWithTypeParameter[S]
。那个是全部的编译器可以知道使用此引用可以做什么。这些类型纯粹用于编译器。在运行时,
a
被分配给
ClassWithTypeParameter[a]
的值这一事实是不相关的


对某种近似值(受擦除限制)执行此操作的一种可能方法是使用清单(在2.10中称为其他内容):


然后您可以调用
erasure
,这将返回
java.lang.Class
。正如我所说,这是有限的。一个类与一个类型不是一回事,并且没有办法区分,例如,
ClassWithTypeParameter[List[Int]]
ClassWithTypeParameter[List[Double]]

以下是一个坏主意(就像反射的大多数用法一样),但它是有效的:

class ClassWithTypeParameter[+T: Manifest] { def erasure = manifest[T].erasure }
这给了我们:

class ClassWithTypeParameter[+T: Manifest] {
  def paramIs[V: Manifest] = manifest[T] == manifest[V]
}
以及:

您可以使用
Manifest
编写类似的
paramsubiteof
paramSupertypeOf
方法

在Scala 2.10(里程碑4或更高版本)中,需要获得以下类型:

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

现在,您可以编写类似于
a.paramType.parents
的内容来获取直接超类型,等等。

但是可以使用清单来区分
CWTP[List[Int]
CWTP[List[Double]]
——如果您进行擦除,就不会了。@oxbow\u谢谢您的解释,这帮了大忙。
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
class ClassWithTypeParameter[+T: TypeTag] {
  def paramType = reflect.runtime.universe.typeTag[T].tpe
}