我希望能够使用基于某些类名的宏创建类型良好的实例。例如,我希望能够像这样创建一个Long
实例:
def fromName[T](typeName: String) = macro FromNameMacro.impl[T]
// will typecheck ok
fromName("scala.Long") ==== 0L
// will not typecheck ok
fromName("scala.Long") ==== ""
实施将类似于:
import scala.reflect.macros.Context
object FromNameMacro {
def impl[T: c.WeakTypeTag](c : Context)(klassName: c.Expr[String]): c.Expr[T] = {
import c.{universe => u}; import u._
val name = klassName.tree match { case Literal(Constant(n)) => n.toString }
// of course this doesn't work...
reify(this.getClass.getClassLoader.loadClass(name).newInstance.asInstanceOf[T])
}
}
我的问题是:
如果类型取决于参数,我需要做什么让宏返回正确类型的对象?
甚至可以使用Scala 2.10吗?
答案 0 :(得分:1)
在2.10.x,
中,返回一个正确类型的结果是非常简单的import scala.language.experimental.macros
import scala.reflect.macros.Context
object fromName {
def apply(tpe: String): Any = macro fromNameImpl
def fromNameImpl(c: Context)(tpe: c.Expr[String]): c.Expr[Any] = {
import c.universe._
c.Expr(tpe.tree match {
case Literal(Constant("scala.Long")) => Literal(Constant(0L))
case Literal(Constant("java.lang.String")) => Literal(Constant(""))
case _ => Literal(Constant(()))
})
}
}
示例REPL会话,
scala> fromName("scala.Long")
res0: Long = 0
scala> fromName("java.lang.String")
res1: String = ""