我试图想出一个通用函数,它可以获取原始数据类型以及扩展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。我的方法有误吗?
答案 0 :(得分:2)
你可以更简单:
def sortedSet[T : Ordering](t:T) = SortedSet(t)(implicitly[Ordering[T]].reverse)
适用于您描述的用例,不需要区分基元和其他对象,也不需要在运行时获取实际类型。调用此函数时,编译器将确保所使用的类型有Ordering
可用(如果没有则可以失败)。
对于Value
的情况,他将根据您对Ordered