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

Elixir中构建枚举类型的最佳实践有哪些?

Elixir枚举类型实现最佳实践推荐

以下是满足不可篡改、支持整数关联、适配对外API和数值计算场景的可行方案:

方案1:模块封装常量+显式转换函数(通用场景首选)

将枚举映射关系封装在模块内部作为编译期常量,完全规避外部修改风险,同时提供标准化的取值、校验接口:

defmodule IceCreamFlavor do
  @moduledoc "冰淇淋口味枚举,内部映射不可外部修改"

  # 编译期固定的枚举-整数映射,外部无法篡改
  @value_map %{
    vanilla: 0,
    chocolate: 1,
    peanut_butter: 2
  }
  @valid_values Map.keys(@value_map)
  @reverse_map Map.new(Enum.map(@value_map, fn {k, v} -> {v, k} end))

  @doc "校验输入是否为合法枚举项"
  def valid?(flavor), do: flavor in @valid_values

  @doc "枚举转对应整数,非法输入直接抛出参数错误"
  def to_int(flavor) when flavor in @valid_values, do: @value_map[flavor]

  @doc "可选:整数反向转换为枚举atom"
  def from_int(int) when int in Map.values(@value_map), do: @reverse_map[int]
end

使用方式适配你提到的两类场景:

  • 对外API参数校验:调用IceCreamFlavor.valid?(param)即可快速判断入参合法性,非法值直接返回参数错误
  • 数值计算场景:调用IceCreamFlavor.to_int(flavor)获取固定整数参与计算即可

针对时间单位转换这类计算密集的枚举场景可以简化封装:

defmodule DurationType do
  @value_map %{
    milliseconds: 1,
    seconds: 1000,
    minutes: 60_000,
    hours: 3_600_000
  }
  @valid_values Map.keys(@value_map)

  def to_milliseconds(value, type) when type in @valid_values do
    value * @value_map[type]
  end
end

# 用法示例:5分钟转毫秒
milliseconds = DurationType.to_milliseconds(5, :minutes) # 返回300000

方案2:Ecto.Enum(数据库交互场景)

如果项目使用Ecto做数据库持久化,可以直接使用官方提供的Ecto.Enum类型,自动完成atom和数据库整数字段的双向转换,同时内置参数校验:

schema "ice_creams" do
  field :flavor, Ecto.Enum, values: [vanilla: 0, chocolate: 1, peanut_butter: 2]
end

业务代码中直接用atom操作即可,不需要手动处理整数映射。

方案3:结合类型声明的类型安全枚举(复杂API场景)

如果需要静态校验能力,可以补充类型规范,配合Dialyzer可以在编译期发现非法传参问题:

defmodule IceCreamFlavor do
  @type t :: :vanilla | :chocolate | :peanut_butter
  # 其他转换逻辑和方案1一致
end

# API函数参数声明枚举类型,静态检查阶段即可发现非法传参
@spec add_kepler_contribution(IceCreamFlavor.t(), float(), list(float())) :: :ok
def add_kepler_contribution(type, gm, p_dot) do
  int_val = IceCreamFlavor.to_int(type)
  # 后续业务逻辑
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:39:04