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)
在代码示例中,提起与未引号剪接的实现是什么?
在两个示例中都在同一时间发生。
UnQuoting 是将Tree
替换为某个地方的Tree
结构(例如插值)的过程。在此示例中,ints
并不是完全Tree
,但是存在Liftable[List[T]]
,它允许我们将List[T]
引用到Tree
中,就好像它是Tree
一样(即Liftable
。 Tree
,以便可以被替换)。
引用文档:
unQuote 剪接是一种揭开不同数量元素的方式。
在这里,元素数量的变量将是我们要取消报价的List
中的元素。如果我们做了q"f($ints)"
,那么我们将仅将ints
作为f
的单个参数。但是,也许我们想将重复参数应用于f
。为此,我们使用 unQuote剪接。
q"f(..$ints) // Using `..` means we get f(1, 2, 3) instead of f(List(1, 2, 3))
再次说明了它最好的说法:
dots接近无引用的注释扁平度,也称为剪接等级。
..$
期望参数为Iterable[Tree]
,...$
期望Iterable[Iterable[Tree]]
。
so 举重允许我们将List[T]
毫无疑问地添加到树f(x)
中,就好像是Iterable[Tree]
一样, unquote splicing 允许我们允许我们取消 List[T]
elements CC_24包含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)