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

如何在Scala 3宏注解中正确匹配TypeDef?

问题原因与解决办法

你的问题核心是混淆了Scala 3 Quoted API中TypeDef与ClassDef的模式匹配逻辑:

  1. 虽然case class对应的ClassDef是TypeDef的子类,因此isInstanceOf[TypeDef]会返回true,但Scala的构造器模式匹配(case td @ TypeDef(_, _))只会匹配直接由TypeDef构造器创建的实例(比如类型别名type X = Int这类定义),不会覆盖它的子类ClassDef。

  2. 要匹配case class的定义,你有两种可行方案:

修改后的代码示例

方案1:直接匹配ClassDef(精准适配类/case class场景)

import scala.annotation.{MacroAnnotation, experimental}
import scala.quoted.*

object Macros:
  @experimental
  class table extends MacroAnnotation:
    def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
      import quotes.reflect.*
      tree match
        case cd @ ClassDef(_, _, _) =>
          report.error(s"from macro annotation1 ${cd.symbol}")
          List(tree)
        case _ =>
          report.error(s"from macro annotation2 $tree")
          List(tree)

方案2:用类型测试模式匹配所有TypeDef子类(覆盖类、特质、类型别名等所有类型定义)

import scala.annotation.{MacroAnnotation, experimental}
import scala.quoted.*

object Macros:
  @experimental
  class table extends MacroAnnotation:
    def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
      import quotes.reflect.*
      tree match
        case td: TypeDef =>
          report.error(s"from macro annotation1 ${td.symbol}")
          List(tree)
        case _ =>
          report.error(s"from macro annotation2 $tree")
          List(tree)

补充说明

在Scala 3的Quoted API层级中:

  • TypeDef是所有类型定义的父类,包含ClassDef(类/case class)、TraitDef(特质)、AliasDef(类型别名)等子类。
  • 构造器模式(如TypeDef(_, _))仅匹配直接实例,子类实例需要通过类型测试模式(: TypeDef)或直接匹配子类构造器(如ClassDef(_,_,_))来捕获。

内容的提问来源于stack exchange,提问作者Csaba Kincses

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:00:02