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

如何实现编译时校验Map包含指定枚举的所有case作为键

实现方案

这类要求覆盖所有枚举键的映射结构通常被称为完备枚举映射(Total Enum Map),Scala生态下有多种实现方式可以满足编译期校验的要求:

方式1:Scala 3 原生实现(无第三方依赖)

通过inline+编译期反射可以直接实现轻量的校验逻辑,代码如下:
首先定义完备映射类型:

import scala.deriving.Mirror
import scala.compiletime.*

// 封装类,代理普通Map的所有能力
final class TotalEnumMap[K <: Enum[K], V] private (val inner: Map[K, V]) extends AnyVal:
  // 直接转发所有Map的原生方法,使用体验和普通Map完全一致
  export inner.*

object TotalEnumMap:
  inline def apply[K <: Enum[K], V](entries: (K, V)*)(using m: Mirror.SumOf[K]): TotalEnumMap[K, V] =
    val allEnumCount = constValue[m.MirroredElemLabels].size
    val inputKeys = entries.map(_._1).toSet
    // 编译期校验:传入的键数量必须等于枚举值总数,且无重复
    if inputKeys.size != allEnumCount then
      error(s"枚举键覆盖不完整:当前仅传入${inputKeys.size}个键,需要覆盖全部${allEnumCount}个枚举值")
    new TotalEnumMap(Map(entries*))

使用示例:

// 编译报错,错误提示:枚举键覆盖不完整:当前仅传入3个键,需要覆盖全部4个枚举值
val invalidMap = TotalEnumMap(
  Connector.CHAdeMO -> 1,
  Connector.Mennekes -> 2,
  Connector.CCS -> 3,
)

// 编译通过
val validMap = TotalEnumMap(
  Connector.CHAdeMO -> 1,
  Connector.Mennekes -> 2,
  Connector.CCS -> 3,
  Connector.Tesla -> 4
)

// 正常使用普通Map的所有方法
validMap(Connector.Tesla) // 返回4
validMap.get(Connector.CHAdeMO) // 返回Some(1)
validMap.contains(Connector.Mennekes) // 返回true

方式2:第三方库实现

如果项目允许引入第三方依赖,Shapeless的异构映射、Cats的Total类型类都有现成的完备映射实现,无需自行编写校验逻辑。

内容的提问来源于stack exchange,提问作者Simão Martins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:27:04