Reputation: 1101
Is it possible to cast some object with the help of its Type
. For example:
import scala.reflect.api.Types
val t: Types#Type = ...// real type of the object o below
println(t) // out: com.project.Event[java.lang.String]
val o: Any = ... // some object which has above type
val e: com.project.Event[java.lang.String] = cast(o, t)
def cast(o: Any, t: Type) = ???
Upvotes: 0
Views: 125
Reputation: 22374
If you use exactly Type
(not TypeTag[T]
) - in general case no, because the instance of Type
doesn't store any information in compile-time: there is no type-level members/parameters storing that info.
So if you use Type
in runtime - there is no way to know which compile-time type it's corresponding to (what is the return type of your cast function? _
? :) ).
So your cast would have to have a signature like:
def cast[T](o: Any, t: Type): T = o.asInstanceOf[T]
in which case Type
doesn't really help as (unlike TypeTag[T]
) it doesn't provide anything for type inference of T
. Even conversion from Type to TypeTag[T]
obviously requires you to specify type explicitly, like cast[String]
and so on.
The only thing Type
can be used for is to check if o
actually corresponds t
:
def cast[T](o: Any, t: Type): Option[T] =
if (mirror.reflect(o).symbol == t.typeSymbol) Some(o.asInstanceOf[T]) else None
up to something like:
def cast[T: TypeTag](o: Any, t: Type): Option[T] =
if (mirror.reflect(o).symbol == t.typeSymbol && typeOf[T] =:= t)
Some(o.asInstanceOf[T])
else None
One obvious exception is when you obtained a Type
inside a macro, so you can compose a tree with correct asInstanceOf
in compile-time:
https://groups.google.com/forum/#!topic/scala-user/3YF_98W9eSE
Upvotes: 1
Reputation: 14217
I think you can use TypeTag for holding the type info and cast it to the target type, like:
import scala.reflect.runtime.universe._
// get TypeTag by typeTag[A]
val t: TypeTag[com.project.Event[java.lang.String]] = typeTag[com.project.Event[java.lang.String]]
//cast with typeTag
val r:com.project.Event[java.lang.String] = cast(o, t)
def cast[A](o: Any, t: TypeTag[A]) = o.asInstanceOf[A]
if you can't get TypeTag
directly, maybe you want to convert the Type
to TypeTag
:
Upvotes: 0