How to pass a variable to a specific type of runtime received from TypeCast in Scala

asInstanceOf[T] works for the β€œsimple” case when the type T is explicitly set by code: for example,

 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 type T is retrieved at run time through TypeTags , asInstanceOf[T] does not work. For instance:

 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 that it is clear that intT not type . So, reflect.runtime.universe.Type not a real type ? How to pass a value to a specific type using typeTag information?

+5
source share
1 answer

intT not a type, but an instance of Type . Vaguely, of course. 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 be different from A given the Any element and 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 option 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 
+8
source

Source: https://habr.com/ru/post/1216636/


All Articles