elixir - 使用模块作为常量

标签 elixir ecto

我正在编写一个自定义的 Ecto 类型,其行为类似于枚举类型。我有一个原子 => 整数的关键字列表。

我意识到我可以使用 Elixir 模块(实际上只是原子)作为我的 key ,而不是常规原子。但我不确定这是否是一种糟糕的形式。

对我来说,使用模块 1) 看起来更重要、更明显,可接受的值在范围内受到限制,2) 提供了一些正确代码建议的机会。

由于它们“只是原子”,我不认为这样做会比其他方式带来更多的性能损失?同时,传递规则原子对于 Elixir 来说似乎更自然一些?

我不太担心错误的原子被插入到数据库中,因为我使用任一方法检查强制转换/转储,这更多是一个风格问题。

这里的最佳实践是什么?你会做什么?

模块作为 key

defmodule App.Background.BackgroundJob.Pool do
  # you could probably macro this if you hated the look of the syntax
  defmodule Local do end
  defmodule Remote do end

  @behaviour Ecto.Type
  @pools [{Local, 0}, {Remote, 1}]

  # cast, load, etc...
end

job  = %{
  pool: BackgroundJob.Pool.Local,
  # ...
}

原子作为 key

defmodule App.Background.BackgroundJob.Pool do

  @behaviour Ecto.Type
  @pools [{:local, 0}, {:remote, 1}]

  # possibly have these functions 
  def local, do: :local
  def remote, do: :remote

  # cast, load, etc...
end

job  = %{
  pool: BackgroundJob.Pool.local,
  # ...
}

# or

job  = %{
  pool: :local,
  # ...
}

最佳答案

没有 Elixir 。我经常使用 Elixir 模块作为键​​,但只有当它们成为一个模块有意义时(附加功能、函数等等)。

这里使用模块只是为了节省几次击键。这对我来说看起来具有误导性和唐突性。为了避免代码重复并通过 DRY,人们可以简单地将模块转换为结构:

defmodule App.Background.BackgroundJob.Pool do
  @enum [local: 0, remote: 1]
  defstruct @enum

  @behaviour Ecto.Type
  @pools @enum

  # cast, load, etc...
end

job  = %{
  pool: BackgroundJob.Pool.local,
  # ...
}

或任何其他提供更清晰的方式,例如宏:

defmodule Enum do
  defmacro __using__(enum) do
    enum
    |> Enum.with_index()
    |> Enum.map(fn {name, idx} ->
      quote location: :keep do
        def unquote(name)(), do: unquote(idx)
      end
    end)
  end
end

use Enum, [:local, :remote]
job  = %{
  pool: BackgroundJob.Pool.local,
  # ...
}

关于elixir - 使用模块作为常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53367268/

相关文章:

Elixir:将符号转换为函数

elixir - 在 Elixir 中启动同一事件处理程序的多个实例

postgresql - 通过ecto存储jsonb数据

postgresql - 到我的docker postgres数据库容器的连接数开始于11?

postgresql - Elixir Postgres 运行 mix ecto.setup 时出现错误 42501?

elixir - 执行命令和流结果

decimal - 在 Elixir 中舍入十进制数

Elixir Ecto : Multiple belongs_to relationship in a schema

elixir - 在 Ecto phoenix.gen.html 中使用 'belongs_to' 出错

elixir - Phoenix/Ecto 变更集出现问题