如何从Scala中的Iterable声明类型?

时间:2016-09-08 05:41:37

标签: json scala type-erasure

我想知道是否有办法在底层的Iterable中获取声明的类型,如:

var string: Seq[String] => I want something to return String 
var int: Seq[Int] = _ => I want something to return Int
var genericType: Seq[A] => I want to return A

我需要知道这些类的类,所以我可以使用底层的Json库将json字符串反序列化为这种类型。

这样的东西
def fromJson[A](jsonString: String)(implicit tag: TypeTag[A]): A =  ???

由于

2 个答案:

答案 0 :(得分:0)

scala> class A(i: Int) {
 | override def toString = "A("+i+")"
 | }
defined class A

scala> class B(i: Int) extends A(i) {
 | override def toString = "B("+i+")"
 | }
defined class B

scala> val list: List[A] = List(new A(1), new B(2), new B(3), new A(4))
list: List[A] = List(A(1), B(2), B(3), A(4)) 

// if you just want the name of class

// full class name with package info
scala> val fullClassNameList = list.map(s => s.getClass.getName)
fullClassNameList: List[String] = List(A, B, B, A)


// If you want the actual runtime Type

scala> import scala.reflect.runtime.{universe=>ru}
import scala.reflect.runtime.{universe=>ru}

scala> def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
getTypeTag: [T](obj: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.TypeTag[T]

// if you just wanted to find the Type parameter of the List,

// get TypeTag of list
val listTypeTag = getTypeTag(list)
listTypeTag: reflect.runtime.universe.TypeTag[List[A]] = TypeTag[scala.List[A]]

// get Type of list
scala> val listType = listTypeTag.tpe
listType: reflect.runtime.universe.Type = scala.List[A]

// get TypeArgs of the Type of list
scala> val listTypeArgs = listType.typeArgs
listTypeArgs: List[reflect.runtime.universe.Type] = List(A)

// Now, we know that List[A] takes just 1 type parameter
// that is the type we are looking for
scala> val theTypeOfList = listTypeArgs.head
theTypeOfList: reflect.runtime.universe.Type = A

答案 1 :(得分:0)

我可能没有在我的问题中提供足够的信息。无论如何,我找到了答案。

为了从泛型类型中检索类,我必须执行以下操作

import scala.reflect.runtime.universe._
val m = runtimeMirror(getClass.getClassLoader)
def myMethod[A](implicit t: TypeTag[A]) = {
  val aType = typeOf[A]
  aType.typeArgs match {
     case x: List[_] if x.nonEmpty => m.runtimeClass(x.head)
     case x: List[_] if x.isEmpty => m.runtimeClass(aType)
  }
}
scala> myMethod[Seq[String]]
res3: Class[_] = class java.lang.String

scala> myMethod[Seq[Int]]
res4: Class[_] = int

scala> case class Person(name: String)
defined class Person

scala> myMethod[Seq[Person]]
res5: Class[_] = class Person

scala> myMethod[Person]
res6: Class[_] = class Person

然后,我可以将此类提供给底层库以完成其工作。 感谢