此文档页面特定于 Scala 2 中提供的功能,这些功能已在 Scala 3 中删除或被替代功能取代。除非另有说明,本页面中的所有代码示例均假定你使用的是 Scala 2。
Scala 2.11
在 Scala 2.11 中,准引号作为 scala-reflect.jar
的一部分在官方 Scala 发行版中提供,因此你无需执行任何特殊操作即可使用它们 - 只需别忘了添加对 scala-reflect
的依赖项。
本指南中的所有示例和代码片段均在 2.11 REPL 中运行,并额外添加了一行
scala> val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
scala> import universe._
从一个 universe(可能是此处类似的运行时反射 universe 或宏中提供的编译时 universe)进行通配符导入是使用准引号所需的全部内容。所有示例都将假定该导入。
此外,一些使用 ToolBox
API 的示例将需要更多行来启动
scala> import scala.reflect.runtime.currentMirror
scala> import scala.tools.reflect.ToolBox
scala> val toolbox = currentMirror.mkToolBox()
另一个你可能想要了解的新工具是漂亮打印机 showCode
(由 @VladimirNik 贡献)
scala> val C = q"class C"
C: universe.ClassDef =
class C extends scala.AnyRef {
def <init>() = {
super.<init>();
()
}
}
scala> println(showCode(C))
class C
默认漂亮打印机以想象的低级 Scala 类似符号显示树的内容。另一方面,showCode
将尽最大努力以适当的 Scala 语法重建与给定树等效的实际源代码。
在频谱的另一端,还有一个 showRaw
漂亮打印机,它显示树的直接内部组织
scala> println(showRaw(q"class C"))
ClassDef(Modifiers(), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("AnyRef"))), noSelfType, List(DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))))))
Scala 2.10
在 Scala 2.10 中,准引号仅通过 宏天堂编译器插件 提供。
简而言之,在 2.10 中使用准引号就像为宏天堂插件添加一个 addCompilerPlugin
行到你的 sbt 构建一样简单,该插件启用准引号,并为准引号在 Scala 2.10 中运行所需的辅助库添加一个额外的 libraryDependencies
行。完整的示例可在 https://github.com/scalamacros/sbt-example-paradise 中找到。
新的 showCode
漂亮打印机在 2.10 中不可用。
sbt 交叉编译
以下是从 Spire 摘取的一个简洁的 sbt 代码段,它允许你使用准引号并针对 Scala 2.10 和 2.11 进行交叉编译
libraryDependencies := {
CrossVersion.partialVersion(scalaVersion.value) match {
// if scala 2.11+ is used, quasiquotes are merged into scala-reflect
case Some((2, scalaMajor)) if scalaMajor >= 11 =>
libraryDependencies.value
// in Scala 2.10, quasiquotes are provided by macro paradise
case Some((2, 10)) =>
libraryDependencies.value ++ Seq(
compilerPlugin("org.scalamacros" % "paradise" % "2.0.0" cross CrossVersion.full),
"org.scalamacros" %% "quasiquotes" % "2.0.0" cross CrossVersion.binary)
}
}