拟引语解释树的内容,而不是按照字面意思



你能解释一下为什么下面Scala的两种用法在result1result2之间会产生不同的输出吗?有可能用拟引法重现result3吗?即解析字符串内容并评估它?

import scala.tools.reflect.ToolBox
import scala.reflect.runtime.universe._
val miniSrc = "val lst = (1 to 5).toList ; val sum = lst.foldLeft(0)(_ + _); sum"
val tree1 = q"$miniSrc"
//tree1: reflect.runtime.universe.Tree = "val lst = (1 to 5).toList ; val sum = lst.foldLeft(0)(_ + _); sum"
val tree2 = q"val lst = (1 to 5).toList ; val sum = lst.foldLeft(0)(_ + _); sum"
//tree2: reflect.runtime.universe.Tree =
//{
//  val lst = 1.to(5).toList;
//  val sum = lst.foldLeft(0)(((x$1, x$2) => x$1.$plus(x$2)));
//  sum
//}
val tb = scala.reflect.runtime.currentMirror.mkToolBox()
val result1 = tb.eval(tree1)
//result1: Any = val lst = (1 to 5).toList ; val sum = lst.foldLeft(0)(_ + _); sum
val result2 = tb.eval(tree2)
//result2: Any = 15
val result3 = tb.eval(tb.parse(miniSrc))
//result3: Any = 15

你能解释一下为什么下面Scala的两种用法在result1result2之间会产生不同的输出吗?

miniSrc是字面量String而不是Treeq"{$miniSrc}" miniSrc(字面量String)提升为另一个Tree。提升不会将任意代码解析为Tree,它只是将树或其他类型拼接到树中。因此,tree1是包含文字StringTree

这个例子应该可以很好地说明为什么将一个字面值字符串提升到树中不应该涉及任何解析:

scala> val miniSrc = "abc"
miniSrc: String = abc
scala> val tree1 = q"$miniSrc"
tree1: reflect.runtime.universe.Tree = "abc"

tree2本质上是不同的,因为您直接使用准引号插入器创建Tree。因此,result1只是一个字面值字符串,而result2tree2中某些执行代码的结果。

是否有可能使用准引号复制result3 ?即解析字符串内容并评估它?

不,这就是解析的作用。如果您想将任意代码作为字符串字面值提升到准引号中,则必须首先将其解析为Tree。否则,它将只是一个文字。

scala> val tree1 = q"${tb.parse(miniSrc)}"
tree1: tb.u.Tree =
{
  val lst = 1.to(5).toList;
  val sum = lst.foldLeft(0)(((x$1, x$2) => x$1.$plus(x$2)));
  sum
}

并不是说当使用宏时,您可以使用宏的Context进行解析。即c.parse(而不是使用ToolBox)。

相关内容

  • 没有找到相关文章

最新更新