Scala宏示例不适用于Scala 2.12.6

时间:2018-08-08 15:14:58

标签: scala macros scala-macros

我正在从here中获取以下代码。

package example.macros
import scala.language.experimental.macros
import scala.reflect.macros.Context
import scala.collection.mutable.{ListBuffer, Stack}

object Macros {
  def printf(format: String, params: Any*): Unit = macro printf_impl

  def printf_impl(c: Context)(format: c.Expr[String], params: c.Expr[Any]*): c.Expr[Unit] = {
    import c.universe._
    val Literal(Constant(s_format: String)) = format.tree

    val evals = ListBuffer[ValDef]()
    def precompute(value: Tree, tpe: Type): Ident = {
      val freshName = TermName(c.fresh("eval$"))
      evals += ValDef(Modifiers(), freshName, TypeTree(tpe), value)
      Ident(freshName)
    }

    val paramsStack = Stack[Tree]((params map (_.tree)): _*)
    val refs = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map {
      case "%d" => precompute(paramsStack.pop, typeOf[Int])
      case "%s" => precompute(paramsStack.pop, typeOf[String])
      case "%%" => Literal(Constant("%"))
      case part => Literal(Constant(part))
    }

    val stats = evals ++ refs.map(ref => reify(print(c.Expr[Any](ref).splice)).tree)
    c.Expr[Unit](Block(stats.toList, Literal(Constant(()))))
  }
}

或在IDE中查看:

IDE

当我尝试在IntelliJ中编译项目时,我得到了:

compile errors

怎么了?我该如何解决?

2 个答案:

答案 0 :(得分:2)

我与IntelliJ完全一样。我通过声明对scala-reflect"org.scala-lang" % "scala-reflect" % "2.12.6")的依赖来解决它。

答案 1 :(得分:0)

从scala 2.11开始,scala.reflect.macros.Context上下文已分为scala.reflect.macros.whitebox.Contextscala.reflect.macros.blackbox.Context

您必须导入想要的一个!

更多说明:https://docs.scala-lang.org/overviews/macros/blackbox-whitebox.html