如何在Scala 3宏注解中正确匹配TypeDef?
问题原因与解决办法
你的问题核心是混淆了Scala 3 Quoted API中TypeDef与ClassDef的模式匹配逻辑:
虽然case class对应的
ClassDef是TypeDef的子类,因此isInstanceOf[TypeDef]会返回true,但Scala的构造器模式匹配(case td @ TypeDef(_, _))只会匹配直接由TypeDef构造器创建的实例(比如类型别名type X = Int这类定义),不会覆盖它的子类ClassDef。要匹配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
相关产品推荐
相关产品推荐

