2

我希望能够使用基于某些类名的宏创建类型良好的实例。例如,我希望能够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 吗?

4

1 回答 1

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 = ""
于 2013-04-03T10:13:26.480 回答