如何通过Mirrors或宏区分Scala 3的Enum与sealed trait?
Scala 3 枚举类型与普通sealed trait区分方案
问题1:是否可以通过Mirrors或宏能力实现识别区分?
可以,两种技术路径都能实现该需求:
- 基于Mirror的方案:Scala 3 为原生枚举自动生成的
Mirror.Sum实例对应的类型会默认继承scala.Enum特质,普通自定义sealed trait没有该继承关系,可通过隐式约束或类型判断区分。该方案不需要写宏代码,但依赖隐式推导,编译开销略高。 - 基于宏的方案:可直接在编译期读取类型符号的内置标记属性,判断逻辑更直接,运行时无开销,也不需要引入额外的隐式依赖,更适合需求场景。
问题2:宏方法实现
你需要的isScalaEnum宏可以按以下代码实现,核心是调用Scala 3 反射API中类型符号的isEnum内置属性:
import scala.quoted.* transparent inline def isScalaEnum[A]: Boolean = ${ isScalaEnumImpl[A] } private def isScalaEnumImpl[A: Type](using q: Quotes): Expr[Boolean] = import q.reflect.* // 获取传入类型的编译期符号,读取isEnum标记 val isEnum = TypeRepr.of[A].typeSymbol.isEnum Expr(isEnum)
问题3:效果验证
使用你给出的测试用例运行,返回结果完全符合预期:
sealed trait T case class A(x: Int) extends T case class B(x: String) extends T enum Color(val rgb: Int): case Red extends Color(1) case Green extends Color(2) // 测试输出 isScalaEnum[T] // false isScalaEnum[Color] // true
补充说明:只有enum的顶层父类才会被标记为枚举类型,单个枚举case(如Color.Red)的isScalaEnum返回值为false,符合语义预期。
内容的提问来源于stack exchange,提问作者Koosha
相关产品推荐
相关产品推荐

