如何获取运行时变量Type并可以将其作为scala中的变量传递?

时间:2015-08-10 13:16:30

标签: scala

我试图想出一个通用函数,它可以获取原始数据类型以及扩展scala.math.Ordering的其他对象。 我查了How to get to type parameters of a reflect.runtime.universe.Type in scala?I want to get the type of a variable at runtime我无法得到答案。 示例如下:     import scala.reflect.runtime.universe._     import scala.collection.SortedSet

def getTypeTag[T: TypeTag](obj: T) = typeTag[T]

def createSortedSet[A: TypeTag](y: A) = typeOf[A] match{
//handle the primitive data types 
case t1 if t1 =:= typeOf[Int] =>
SortedSet(y)(implicitly[Ordering[Int]].reverse)
case t2 if t2 =:= typeOf[Long] =>
SortedSet(y)(implicitly[Ordering[Long]].reverse)
.....
// last part handle any object that implements Comparable
case tx if tx.getClass.getInterfaces.exists( _.toString == "interface java.lang.Comparable") =>
{// trying to get the type of the variable and then pass in to the Ordering
 val TT: Type = getTypeTag(t).tpe
SortedSet(y)(implicitly[Ordering[TT]].reverse)}
case _ => ...
}

所以为了传入一个对象并让Ordering完成它的工作,我需要将类型传递给Ordering,假设我创建了一个扩展Ordering的case类

case class Value(i: Int) extends Ordered[Value] {def compare(that: Value) = this.i - that.i}
val v1 = Value(3)
// now I want to get a SortedSet instance by calling the createSortedSet
 createSortedSet(v1)

当我进行上述调用时出错,所以我认为reflect.runtime.universe.Type并不能真正用作Type。我的方法有误吗?

1 个答案:

答案 0 :(得分:2)

你可以更简单:

 def sortedSet[T : Ordering](t:T) = SortedSet(t)(implicitly[Ordering[T]].reverse)

适用于您描述的用例,不需要区分基元和其他对象,也不需要在运行时获取实际类型。调用此函数时,编译器将确保所使用的类型有Ordering可用(如果没有则可以失败)。 对于Value的情况,他将根据您对Ordered

的实施情况隐式提供一个