Reputation: 6332
With the following code,new Box(10), new Box("20")
works well for me. But for the new Box(Seq(20)), new Box(Seq("20")))
,
I would like to figure out the type of type parameter for the Seq, so that I could print Seq[Int], Seq[String]
@Test
def testClassTag(): Unit = {
class Box[T:ClassTag](val data: T) {
def printTypeParameter() = {
val tag = implicitly[ClassTag[T]].runtimeClass
tag match {
case _ if tag == classOf[Int] => println("Int")
case _ if tag == classOf[String] => println("String")
case _ if tag == classOf[Seq[_]] => println( "Seq")
}
}
}
val boxes = Seq(new Box(10), new Box("20"), new Box(Seq(20)), new Box(Seq("20")))
boxes.foreach(_.printTypeParameter())
}
Upvotes: 0
Views: 152
Reputation: 6332
@dima's answer is elegant, I would put another way that detects the type parameter step by step.
@Test
def testTypeTag1(): Unit = {
class Box[T: TypeTag](val data: T) {
def printTypeParameter() = {
typeOf[T] match {
case t if t =:= typeOf[Int] => println("Int")
case t if t =:= typeOf[String] => println("String")
case t if t <:< typeOf[Seq[Any]] => {
val TypeRef(_, _, Seq(elementType)) = typeOf[T]
elementType match {
case t if t =:= typeOf[Int] =>println("Seq[Int]")
case t if t =:= typeOf[String] =>println("Seq[String]")
case _=>println("Seq[Unknown]")
}
}
case _ => println("Unknown")
}
}
}
val boxes = Seq(new Box(10), new Box("20"), new Box(Seq(20)), new Box(Seq("20")))
boxes.foreach(_.printTypeParameter())
}
Upvotes: 1
Reputation: 40500
The new proper way to do it is using TypeTag
instead of ClassTag
:
def foo[T : TypeTag](data: T) = typeOf[T] match {
case t if t =:= typeOf[Int] => println("Int")
case t if t =:= typeOf[String] => println("String")
case t if t <:< typeOf[Seq[String]] => println("Seq[String]")
// etc
}
(If you just want to print it out, you can as well do this:
def foo[T : TypeTag](data: T) = println(typeOf[T])`
it does the same thing, but handles all types, not just the ones you could think of.
Upvotes: 2