準引號

相依性與設定

語言
此文件頁面特定於 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)進行萬用字元匯入,即可使用 quasiquotes。所有範例都會假設這個匯入。

此外,某些使用 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 中,quasiquotes 只能透過 巨集 paradise 編譯器外掛程式 取得。

簡而言之,在 2.10 中使用 quasiquotes 就像為 sbt 建置新增一行 addCompilerPlugin 給 macro paradise 外掛程式以啟用 quasiquotes,以及一行 libraryDependencies 給支援函式庫,這對於 quasiquotes 在 Scala 2.10 中運作是必要的。完整的範例提供於 https://github.com/scalamacros/sbt-example-paradise

新的 showCode 漂亮列印器在 2.10 中不可用。

sbt 交叉編譯

以下是從 Spire 取得的精簡 sbt 片段,它允許你使用 quasiquotes,並同時針對 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)
  }
}

此頁面的貢獻者