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

如何在Scala 3中对enum类型实现模式匹配

解决方案

Scala 3的枚举类型分两种匹配场景,对应不同的安全实现方式:

场景1:匹配枚举实例

Scala 3中所有枚举实例默认实现了scala.reflect.Enum公共特质,直接按该类型匹配即可,无编译告警、无运行时额外开销:

obj match {
  case e: scala.reflect.Enum =>
    // 枚举实例的处理逻辑
  case other =>
    // 其他类型的处理逻辑
}

场景2:匹配枚举伴生对象(调用values拿所有枚举值)

你之前使用的结构类型{ def values: Array[?] }依赖运行时反射访问,不仅会触发编译告警,scaladoc生成阶段的反射检查还会抛出你遇到的InvocationTargetException异常,推荐使用两种安全替代方案:

方案A:运行时轻量检测

直接通过类名和父类特征判断,避免结构类型语法:

extension (obj: AnyRef)
  private def isEnumCompanion: Boolean =
    val cls = obj.getClass
    // 伴生类名以$结尾,对应的普通类是Enum的子类
    cls.getName.endsWith("$") && 
    classOf[scala.reflect.Enum].isAssignableFrom(Class.forName(cls.getName.dropRight(1)))

// 模式匹配写法
obj match {
  case companion if companion.isEnumCompanion =>
    val values = companion.getClass.getMethod("values").invoke(companion).asInstanceOf[Array[? <: Enum]]
    // 处理逻辑
  case other =>
}
方案B:编译期类型派生(更安全,无反射)

如果是在泛型上下文中使用,推荐用类型类派生方案,完全在编译期完成检查,无任何运行时开销:

import scala.deriving.Mirror
import scala.compiletime.summonAll

// 定义枚举伴生的类型类
trait EnumValues[E <: Enum]:
  def values: Array[E]

object EnumValues:
  // 自动为所有枚举类型派生实例
  inline given [E <: Enum](using m: Mirror.SumOf[E]): EnumValues[E] =
    new EnumValues[E]:
      override val values: Array[E] = 
        summonAll[Tuple.Map[m.MirroredElemTypes, ValueOf]]
          .toList.asInstanceOf[List[ValueOf[E]]]
          .map(_.value)
          .toArray

使用时直接引入上下文即可,不需要做运行时模式匹配:

def processEnum[E <: Enum : EnumValues](): Unit =
  val allValues = summon[EnumValues[E]].values
  // 处理逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:45:04