Scala Quasiquote提升

Roy*_*man 4 scala scala-quasiquotes

Quasiquotes的Scala文档在解释提升时提到了这一点:

也可以结合提升和非提示拼接:

 scala> val ints = List(1, 2, 3)
 scala> val f123 = q"f(..$ints)"
 f123: universe.Tree = f(1, 2, 3)

 scala> val intss = List(List(1, 2, 3), List(4, 5), List(6))
 scala> val f123456 = q"f(...$intss)"
 f123456: universe.Tree = f(1, 2, 3)(4, 5)(6)
Run Code Online (Sandbox Code Playgroud)

具体是代码示例中的提升与非引用拼接的实现?

Mic*_*jac 5

两个例子都在两个例子中同时发生.

Unquoting是将Tree某个地方代入另一个地方的过程Tree(如插值).在这个例子中,ints不完全是Tree,但存在Liftable[List[T]],使我们能够解除引用List[T]到一个Tree,就好像它是一个Tree(即在Liftable告诉编译器如何改造字面List[Int]这里变成Tree这样它可以被取代) .

引用文档:

拼接拼接是一种取消引用可变数量元素的方法.

这里,可变数量的元素将是List我们想要取消引用的元素.如果我们这样做了q"f($ints)",那么我们就可以简单地将其ints作为单一论点f.但也许我们想要应用重复的参数f.为此,我们使用非引号拼接.

q"f(..$ints) // Using `..` means we get f(1, 2, 3) instead of f(List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)

再次,文档说它最好,真的:

无条件附近的点注释扁平度,也称为拼接等级...$期望论证是Iterable[Tree]...$预期的Iterable[Iterable[Tree]].

因此,提升允许我们List[T]在树中取消引用f(x),就好像它是一个Iterable[Tree],并且非引号拼接允许我们取消List[T]引用包含的可变数量的元素作为多个参数f.


以下是不同的相关组合:

val listTree = q"scala.collection.immutable.List(1, 2, 3)"
val treeList = List(q"1", q"2", q"3")
val literalList = List(1, 2, 3)

scala> q"f($listTree)" // plain unquoting from another Tree
res6: reflect.runtime.universe.Tree = f(scala.collection.immutable.List(1, 2, 3))

scala> q"f($literalList)" // unquoting from lifting
res7: reflect.runtime.universe.Tree = f(scala.collection.immutable.List(1, 2, 3))

scala> q"f(..$treeList)" // plain unquote splicing
res8: reflect.runtime.universe.Tree = f(1, 2, 3)

scala> q"f(..$literalList)" // unquote splicing and lifting
res9: reflect.runtime.universe.Tree = f(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)