翻译如下:
这可能是一个很容易回答的问题。也许也很容易找到答案。然而,几个小时后我还是找不到它。 Scala API 的文档
scala.quoted.Quotes.reflectModule
不是很有帮助。
我需要知道如何使用 Scala 3.5.1 的元编程来获取在常规类(不是 case 类)的主构造函数中声明的字段的值。
具体来说,我需要实现下面的
select
函数。最好有拼接和引号。
我在下面添加了
toStrImpl
方法作为使用示例,只是为了提供该问题的上下文和目的。
/** Given the expression `productExpr` that gets an instance of a regular class, and the symbol of a parameter of said class' primary-constructor, obtain the expression that gets the value of said parameter. */
def select[A: Type](using quotes: Quotes)(productExpr: Expr[A], elemSymbol: quotes.reflect.Symbol): Expr[Any] =
??? // TODO implement
def toStrImpl[A: Type](product: Expr[A])(using quotes: Quotes): Expr[String] = {
import quotes.reflect.*
val productSymbol: Symbol = TypeRepr.of[A].typeSymbol
val primaryConstructor: Symbol = productSymbol.primaryConstructor
val paramsLists: List[List[Symbol]] = primaryConstructor.paramSymss
val argsListExprList: List[Expr[List[Any]]] =
for {
paramsList <- paramsLists
if paramsList.forall(_.isTerm) // skips type parameters
} yield {
val argsExprsList: List[Expr[Any]] =
for param <- paramsList yield {
val argValueExpr: Expr[Any] = select(product, param)
'{ $argValueExpr.toString }
}
val argsListExpr: Expr[List[Any]] = Expr.ofList(argsExprsList)
argsListExpr
}
val argsListsExpr: Expr[List[List[Any]]] = Expr.ofList(argsListExprList)
'{
val argsLists = for argsList <- $argsListsExpr yield argsList.mkString("(", ", ", ")")
argsLists.mkString("(", "", ")")
}
}