我正在玩Scala宏。在阅读示例时,我经常会看到这种模式:
Select(
Select(
Ident(TermName("scala")),
TermName("Some")
),
TermName("apply")
)
这是非常冗长和重复的。有没有办法更简洁地表达这一点?我正在寻找类似的东西:
select("scala.Some.apply")
答案 0 :(得分:2)
不要注意评论者。 [编者按:干幽默警报。]
只有真正理智的人才会使用quasiquotes。
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0).
Type in expressions to have them evaluated.
Type :help for more information.
scala> q"scala.Some(42)"
res0: reflect.runtime.universe.Tree = scala.Some(42)
scala> showRaw(res0)
res1: String = Apply(Select(Ident(TermName("scala")), TermName("Some")), List(Literal(Constant(42))))
scala> showRaw(q"scala.Some.apply")
res2: String = Select(Select(Ident(TermName("scala")), TermName("Some")), TermName("apply"))
scala> showRaw(q"scala.Some")
res3: String = Select(Ident(TermName("scala")), TermName("Some"))
scala> showRaw(tq"scala.Some")
res4: String = Select(Ident(TermName("scala")), TypeName("Some"))
通常,您使用qq来记录非常复杂的表达式:
// tq"scala.Some"
val t = Select(Ident(TermName("scala")), TypeName("Some"))
答案 1 :(得分:0)
解决这个问题的一个简单方法是实现以下功能:
def select(identifier : String) : Tree = {
val terms = identifier.split("\\.").map { TermName(_) }
terms.tail.foldLeft[Tree](Ident(terms.head)) { Select(_, _) }
}
REPL的示例输出:
scala> select("scala")
res0: Tree = Ident(TermName(scala))
scala> select("scala.Some")
res1: Tree = Select(Ident(TermName(scala)),TermName(Some))
scala> select("scala.Some.apply")
res2: Tree = Select(Select(Ident(TermName(scala)),TermName(Some)),TermName(apply))
现在,我不知道这是否会以某种方式阻止某些编译器优化,如果明确写出AST,可能会执行其他优化......