You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala 3宏中如何递归实现类型参数的规范化命名?

解决Scala 3元编程中递归规范化类型名称的问题

要实现递归规范化嵌套类型的名称,你需要把类型处理逻辑抽成可递归调用的辅助函数,对每个类型参数递归执行规范化操作。以下是修改后的代码:

object Playpen:
  import scala.quoted.*

  inline def recursiveCanonicalName[T]: String = ${Playpen.recursiveCanonicalNameImpl[T]}

  def recursiveCanonicalNameImpl[T](using Quotes)(using Type[T]): Expr[String] =
    canonicalizeTypeRepr(TypeRepr.of[T])

  // 递归处理TypeRepr的辅助函数
  private def canonicalizeTypeRepr(repr: TypeRepr)(using Quotes): Expr[String] =
    import quotes.reflect.*
    repr.widenTermRefByName.dealias match
      case AppliedType(name, args) =>
        // 处理类型名称
        val nameExpr = Expr(name.dealias.simplified.show)
        // 递归处理每个类型参数,得到对应的表达式
        val argExprs = args.map(canonicalizeTypeRepr)
        // 拼接参数表达式,用逗号分隔
        val joinedArgs = argExprs.reduceOption { (a, b) =>
          Expr.splice(a) + Expr(",") + Expr.splice(b)
        }.getOrElse(Expr(""))
        // 拼接最终的类型字符串表达式
        nameExpr + Expr("[") + joinedArgs + Expr("]")
      case _ =>
        // 基础类型直接返回规范化后的名称
        Expr(repr.dealias.simplified.show)

关键修改说明:

  • 提取辅助函数:将类型处理逻辑移到canonicalizeTypeRepr,方便对任意TypeRepr(包括类型参数)递归调用。
  • 递归处理参数:遇到AppliedType时,对每个类型参数递归调用canonicalizeTypeRepr,确保嵌套类型(比如Seq[String]里的String)也被规范化。
  • Expr拼接:使用Expr.splice将递归生成的字符串表达式正确拼接,避免直接字符串拼接导致的递归失效问题。

测试验证:

修改后再测试嵌套类型:

@ macroplay.Playpen.recursiveCanonicalName[Map[Seq[String],Seq[String]]] 
res: String = "scala.collection.immutable.Map[scala.collection.immutable.Seq[java.lang.String],scala.collection.immutable.Seq[java.lang.String]]"

可以看到,Seq的参数String也被正确规范化为java.lang.String,实现了多层嵌套类型的递归处理。

内容的提问来源于stack exchange,提问作者Steve Waldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:05:13