在其类型的帮助下投射一些对象

时间:2017-09-20 06:15:17

标签: scala reflection

是否可以在Type的帮助下施放一些物体。例如:

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) = ???

2 个答案:

答案 0 :(得分:1)

如果你正好使用Type(而不是TypeTag[T]) - 一般情况下没有,因为Type的实例在编译时没有存储任何信息:没有类型存储该信息的级别成员/参数。

因此,如果在运行时使用Type,则无法知道它与哪个编译时类型对应(什么是转换函数的返回类型?_?:))。

所以你的演员必须有一个签名:

def cast[T](o: Any, t: Type): T = o.asInstanceOf[T]

在这种情况下Type并不真正有用(与TypeTag[T]不同),它不会为T的类型推断提供任何内容。即使conversion from Type to TypeTag[T]显然也要求您明确指定类型,例如cast[String]等等。

Type唯一可以用来检查o是否真正对应t

def cast[T](o: Any, t: Type): Option[T] = 
  if (mirror.reflect(o).symbol == t.typeSymbol) Some(o.asInstanceOf[T]) else None

类似于:

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

一个明显的例外是当你在宏中获得Type时,你可以在编译时用正确的asInstanceOf组成一个树:

https://groups.google.com/forum/#!topic/scala-user/3YF_98W9eSE

答案 1 :(得分:0)

我认为您可以使用TypeTag来保存类型信息并将其转换为目标类型,例如:

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]

如果您无法直接获得TypeTag,也许您想将Type转换为TypeTag

Get a TypeTag from a Type?