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

Scala扩展Case Object实现可继承枚举状态的方案咨询

核心问题梳理

  • 类型继承错误:B、C的伴生对象无需继承A,且你代码中B的apply方法返回值写为C属于明显笔误,编译无法通过
  • 子类型不兼容:A中定义的A1、A2是A类型实例,不属于B/C子类型,直接拼接A.vectA到B/C的状态列表中,元素类型会升级为A,无法满足返回B/C类型的要求
  • 类型匹配错误:getOrElse返回字符串"error",和期望返回的枚举类型不匹配,编译直接报错
  • 匹配规则不稳定:依赖case object默认的toString做匹配,后续如果修改对象命名会直接导致匹配失效

正确实现方案

下面是Scala原生实现方案,无需引入第三方依赖:

第一步:改造基础父trait

统一状态编码字段,避免依赖默认toString做匹配:

trait A {
  // 显式定义状态编码,匹配逻辑更稳定
  def code: String
}

object A {
  // 通用状态定义,此处为def方便子类型复用逻辑
  def A1: A = new A { override val code = "A1" }
  def A2: A = new A { override val code = "A2" }
  val vectA: Vector[A] = Vector(A1, A2)
}

第二步:实现B子类型的枚举和apply方法

单独定义属于B类型的通用状态实例,保证类型合规:

trait B extends A

object B {
  // B自定义扩展状态
  case object B1 extends B { override val code = "B1" }
  case object B2 extends B { override val code = "B2" }
  // 实现属于B类型的通用状态,保证返回值类型符合要求
  case object A1 extends B { override val code = "A1" }
  case object A2 extends B { override val code = "A2" }

  // 全量B类型状态列表
  private val allStates: Vector[B] = Vector(B1, B2, A1, A2)

  def apply(status: String): B = allStates.find(_.code == status)
    .getOrElse(throw new IllegalArgumentException(s"非法B类型状态:$status"))
}

第三步:同理实现C子类型

trait C extends A

object C {
  case object C1 extends C { override val code = "C1" }
  case object C2 extends C { override val code = "C2" }
  case object A1 extends C { override val code = "A1" }
  case object A2 extends C { override val code = "A2" }

  private val allStates: Vector[C] = Vector(C1, C2, A1, A2)

  def apply(status: String): C = allStates.find(_.code == status)
    .getOrElse(throw new IllegalArgumentException(s"非法C类型状态:$status"))
}

效果验证

调用val x = B("A1")即可得到B类型的实例,完全符合需求。如果不想重复写通用状态的定义,可使用Scala宏或者枚举类库简化重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 06:39:03