如何使用 scala 3.5.1 宏获取在其主构造函数中声明的常规类字段的 `Expr`?

问题描述 投票:0回答:1

翻译如下:


这可能是一个很容易回答的问题。也许也很容易找到答案。然而,几个小时后我还是找不到它。 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("(", "", ")")
        }
    }
macros scala-3
1个回答
0
投票

调用“scala”

scala
不可变使用严格的双冒号 ::

想象一下鳄鱼有两个头 :: {} ~;

© www.soinside.com 2019 - 2024. All rights reserved.