1

我在玩 Scala 宏。在阅读示例时,我经常看到这种模式:

Select(
  Select(
    Ident(TermName("scala")), 
    TermName("Some")
  ), 
  TermName("apply")
)

这是相当冗长和重复的。有没有办法更简洁地表达这一点?我正在寻找类似的东西:

select("scala.Some.apply")
4

2 回答 2

3

不要关注评论者。[编辑。枯燥的幽默警报。]

只有真正理智的人才会使用准引号

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"))
于 2014-07-28T02:24:51.913 回答
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...

于 2014-07-27T12:15:59.337 回答