import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
def getType[T: TypeTag](obj: T) = typeOf[T]
case class Thing(
val id: Int,
var name: String
)
val thing = Thing(1, "Apple")
val dataType = getType(thing).decl(TermName("id")).asTerm.typeSignature
dataType match {
case t if t =:= typeOf[Int] => println("I am Int")
case t if t =:= typeOf[String] => println("String, Do some stuff")
case _ => println("Absurd")
}
无法消化为什么结果Absurd
不是I am int
?
我的目的是在运行时了解类参数的数据类型,并将其与预定义类型匹配。
当前dataType
和typeOf[Int]
都打印为,Int
但是如果你这样做showRaw
,将会看到为什么它们不匹配的原因
showRaw(dataType) // NullaryMethodType(TypeRef(ThisType(scala), scala.Int, List()))
showRaw(typeOf[Int]) // TypeRef(ThisType(scala), scala.Int, List())
事实是,Int
返回的空方法的类型和类型Int
是不同的类型。
尝试添加 .resultType
val dataType = getType(thing).decl(TermName("id")).asTerm.typeSignature.resultType
dataType match {
case t if t =:= typeOf[Int] => println("I am Int")
case t if t =:= typeOf[String] => println("String, Do some stuff")
case _ => println("Absurd")
} // I am Int
还值得一提的是.decl(TermName("id"))
,它会返回getter符号,它.decl(TermName("id "))
(带有空格)将返回字段符号。因此,你也可以在符号名称中使用空格,而无需.resultType
val dataType = getType(thing).decl(TermName("id ")).asTerm.typeSignature
我将添加到@TomerShetah的答案中,如果目标是“模式匹配” case类的所有字段,那么也可以在编译时(主要是使用Shapeless)完成此操作:
import shapeless.Poly1
import shapeless.syntax.std.product._
object printTypes extends Poly1 {
implicit val int: Case.Aux[Int, Unit] = at(t => println(s"I am Int: $t"))
implicit val string: Case.Aux[String, Unit] = at(t => println(s"String, Do some stuff: $t"))
implicit def default[V]: Case.Aux[V, Unit] = at(t => println(s"Absurd: $t"))
}
thing.toHList.map(printTypes)
// I am Int: 1
// String, Do some stuff: Apple
https://scastie.scala-lang.org/DmytroMitin/N4Idk4KcRumQJZE2CHC0yQ