我想在运行时获得一个variables的types

我想在运行时获得一个variables的types。 我如何做到这一点?

所以,严格来说,“variables的types”总是存在的,可以作为typesparameter passing。 例如:

val x = 5 def f[T](v: T) = v f(x) // T is Int, the type of x 

但取决于你想做什么 ,这不会帮助你。 例如,可能不想知道variables的types是什么,但要知道的types是否是某种特定的types,比如:

 val x: Any = 5 def f[T](v: T) = v match { case _: Int => "Int" case _: String => "String" case _ => "Unknown" } f(x) 

这里variablesAny的types是什么都没有关系。 重要的是,检查的是5的types,价值。 事实上, T是没用的 – 你也可以写下def f(v: Any) 。 此外,它使用ClassTag或值的Class ,这将在下面解释,并且不能检查types的types参数:您可以检查是否某个List[_] (某个List[_] ),而不是它是否为例如, List[Int]List[String]

另一种可能是你想要确定variables的types。 也就是说,你想将types转换为一个值,所以你可以存储它,传递它等。这涉及到reflection,你将使用ClassTagTypeTag 。 例如:

 val x: Any = 5 import scala.reflect.ClassTag def f[T](v: T)(implicit ev: ClassTag[T]) = ev.toString f(x) // returns the string "Any" 

一个ClassTag也可以让你使用在match收到的types参数。 这不会工作:

 def f[A, B](a: A, b: B) = a match { case _: B => "A is a B" case _ => "A is not a B" } 

但是这将会:

 val x = 'c' val y = 5 val z: Any = 5 import scala.reflect.ClassTag def f[A, B: ClassTag](a: A, b: B) = a match { case _: B => "A is a B" case _ => "A is not a B" } f(x, y) // A (Char) is not a B (Int) f(x, z) // A (Char) is a B (Any) 

在这里,我使用上下文边界语法B : ClassTag ,它与上一个ClassTag示例中的隐式参数一样工作,但使用了一个匿名variables。

我们也可以从一个值的Class获得一个ClassTag ,像这样:

 val x: Any = 5 val y = 5 import scala.reflect.ClassTag def f(a: Any, b: Any) = { val B = ClassTag(b.getClass) ClassTag(a.getClass) match { case B => "a is the same class as b" case _ => "a is not the same class as b" } } f(x, y) == f(y, x) // true, a is the same class as b 

ClassTag是有限的,它只覆盖基类,但不包括types参数。 也就是说, List[Int]List[String]ClassTag是相同的List 。 如果您需要types参数,则必须使用TypeTag 。 然而, TypeTag不能从一个值获得,也不能用于模式匹配,因为JVM的擦除

TypeTag例子TypeTag会变得相当复杂 – 即使比较两个types标签也不是很简单,如下所示:

 import scala.reflect.runtime.universe.TypeTag def f[A, B](a: A, b: B)(implicit evA: TypeTag[A], evB: TypeTag[B]) = evA == evB type X = Int val x: X = 5 val y = 5 f(x, y) // false, X is not the same type as Int 

当然,还有一些方法可以使这种比较成为可能,但是这需要一些书本章来真正涵盖TypeTag ,所以我会在这里停下来。

最后,也许你根本不关心variables的types。 也许你只是想知道什么是价值的阶级,在这种情况下,答案很简单:

 val x = 5 x.getClass // int -- technically, an Int cannot be a class, but Scala fakes it 

然而,要更加具体地说明你想要完成什么,那么答案就更重要了。

我认为这个问题是不完整的。 如果你的意思是你想获得一些typestypes的信息,那么下面是:

如果您希望按照您的指定进行打印,则:

 scala> def manOf[T: Manifest](t: T): Manifest[T] = manifest[T] manOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T] scala> val x = List(1,2,3) x: List[Int] = List(1, 2, 3) scala> println(manOf(x)) scala.collection.immutable.List[Int] 

如果你是在repl模式然后

 scala> :type List(1,2,3) List[Int] 

或者如果你只是想知道什么类的types,然后@monkjack解释"string".getClass可能会解决的目的

如果通过variables的types来表示variables所指向的对象的运行时类,那么可以通过所有对象所具有的类引用来获得该variables。

 val name = "sam"; name: java.lang.String = sam name.getClass res0: java.lang.Class[_] = class java.lang.String 

如果你的意思是variables声明的types,那么你不能得到这个。 例如,如果你说

 val name: Object = "sam" 

那么你仍然会从上面的代码中得到一个String

我已经testing,它的工作

 val x = 9 def printType[T](x:T) :Unit = {println(x.getClass.toString())}