The asInstanceOf[T]
works for "simple" case where the type T
is given explicitly by code: e.g.
scala> val x: Any = 5
x: Any = 5
scala> x.asInstanceOf[Int]
res50: Int = 5
scala> val m1: Any = Map[String, Int]("a"->1, "b"->2)
m1: Any = Map(a -> 1, b -> 2)
scala> m.asInstanceOf[Map[String, Int]]
res51: Map[String,Int] = Map(a -> 1, 2 -> b)
scala> val m2: Any = Map[Any,Any]("a"->1, 2->"b")
m2: Any = Map(a -> 1, 2 -> b)
scala> m.asInstanceOf[Map[Any, Any]]
res52: Map[Any,Any] = Map(a -> 1, 2 -> b)
But when the type T
is retrieved at runtime through TypeTags
, asInstanceOf[T]
does not work. For example:
scala> val intT = typeTag[Int].tpe
intT: reflect.runtime.universe.Type = Int
scala> x.asInstanceOf[intT]
<console>:12: error: not found: type intT
x.asInstanceOf[intT]
The error says it clear that intT
is not a type
. So reflect.runtime.universe.Type
is not a real type
? How to cast a value to certain type using typeTag
information?
intT
isn't a type, but an instance of Type
. Confusing, for sure. I'm not sure if there is something built into the reflection API that does this, but you can easily write a method that will cast to A
given an element Any
and a TypeTag[A]
.
def cast[A](a: Any, tt: TypeTag[A]): A = a.asInstanceOf[A]
scala> val intT = typeTag[Int]
intT: reflect.runtime.universe.TypeTag[Int] = TypeTag[Int]
scala> val a: Any = 1
a: Any = 1
scala> cast(a, intT)
res101: Int = 1
Another variant using an implicit class:
implicit class TypeTagCast(a: Any) {
def fromTypeTag[A](tt: TypeTag[A]): A = a.asInstanceOf[A]
}
scala> a.fromTypeTag(intT)
res106: Int = 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With