此文件頁面專屬於 Scala 3,可能涵蓋 Scala 2 中沒有的新概念。除非另有說明,此頁面中的所有程式碼範例都假設您使用的是 Scala 3。
我應該使用 Expr(...)
或 '{...}
?
如果您可以使用 Expr(...)
編寫程式碼,您將在編譯時進行更多評估。只有在您真的需要在執行時稍後評估程式碼時才使用 '{...}
,通常是因為它取決於執行時的值。
在 Expr(true)
或 '{true}
之間哪一個比較好?
包含基本類型值的引號已最佳化為 Expr.apply
。在專案中選擇一個,並堅持使用單一符號以避免混淆。
如何從 Expr
中取得值?
如果表達式表示一個值,您可以使用 .value
、.valueOrAbort
或 Expr.unapply
如何取得 Expr
的精確類型?
我們可以使用以下模式比對取得 Expr
的精確類型 (Type
)
val x: Expr[X] = ...
x match
case '{ $x: t } =>
// `x: Expr[X & t]` where `t` is the precise type of `x`
如何呼叫元組類型的所有類型?
如果我有一個類型 (T1, T2, ...)
,我如何產生 (summon[T1], summon[T2], ...)
的術語,或取得個別表達式和呼叫的值?
根據您的使用案例,呼叫它們的方式會有所不同。特別是,您需要的程式碼取決於您想要的輸出類型 (Expr[Tuple]
、List[Expr[Any]]
或其他類型) 以及您需要如何報告錯誤。以下是兩個範例,應該會提供這段程式碼兩個不同變體的基本架構。
def summonAllInList[T](using Type[T])(using Quotes): List[Expr[Any]] = {
Type.of[T] match
case '[ head *: tail ] =>
Expr.summon[head] match
case Some(headExpr) => headExpr :: summonAllInList[tail]
case _ => quotes.reflect.report.throwError(s"Could not summon ${Type.show[head]}")
case '[ EmptyTuple ] => Nil
case _ => quotes.reflect.report.throwError(s"Could not `summonAllInList` of tuple with unknown size: ${Type.show[T]}")
}
def summonAll[T](using Type[T])(using Quotes): Option[Expr[Tuple]]] = {
Type.of[T] match
case '[ head *: tail ] =>
for headExpr <- Expr.summon[head]
tailExpr <- summonAll[tail]
yield '{ headExpr *: tailExpr }
case '[ EmptyTuple ] => Some('{ EmptyTuple })
case _ => None
}
如何呼叫靜態未知類型的表達式?
您可以從 TypeRepr
或 Type
呼叫表達式,如下所示。
如果您有 TypeRepr
,請使用
val tpe: TypeRepr = ...
Implicits.search(tpe) match
case result: ImplicitSearchSuccess => result.tree
case _ =>
相反地,如果你有 Type[_]
使用
val tpe: Type[_] = ...
tpe match
// (1) Use `a` as the name of the unknown type and (2) bring a given `Type[a]` into scope
case '[a] => Expr.summon[a]