使用元组作为Elixir中函数的参数

Dav*_*man 2 elixir argument-unpacking

我正在Elixir写一个游戏引擎.(是的,我知道它不是一种本身就适合的语言 - 关键是要看一下非典型语言的使用如何影响结果的结构.)

因此,我有几个主管要在比赛开始时运行 - 但他们应该监督什么取决于游戏.我的想法是让用户在config.exs文件中列出必要的子节点,加上参数和选项作为元组列表,然后管理程序本身只是从应用程序环境中提取这些元组并使用它们的内容作为参数worker\2(或者worker\3,视情况而定).

但是,我找不到任何Elixir等同于Python的元组解包.我可以通过一个简单的函数自己完成这个特定的情况:

def unpack_worker({module, args}) do
  worker(module, args)
end

def unpack_worker({module, args, opts}) do
  worker(module, args, opts)
end
Run Code Online (Sandbox Code Playgroud)

但这种情况充其量只是笨拙,并且必须再次针对我可能需要这种可配置性的每个功能进行编写.

Dog*_*ert 6

我相信你在寻找Tuple.to_list/1apply/3:

有了这些,你可以根据元组的内容调用正确的arity函数:

def unpack_worker(args) do
  apply(__MODULE__, :worker, Tuple.to_list(args))
end
Run Code Online (Sandbox Code Playgroud)

如果你现在打电话unpack_worker({}),它会打电话worker(),unpack_worker({:foo})打电话worker(:foo),等等.

演示:

defmodule A do
  def worker, do: IO.puts 0
  def worker(_), do: IO.puts 1
  def worker(_, _), do: IO.puts 2
  def worker(_, _, _), do: IO.puts 3

  def unpack_worker(tuple), do: apply(__MODULE__, :worker, Tuple.to_list(tuple))
end

A.unpack_worker({})
A.unpack_worker({:a})
A.unpack_worker({:a, :b})
A.unpack_worker({:a, :b, :c})
Run Code Online (Sandbox Code Playgroud)

输出:

0
1
2
3
Run Code Online (Sandbox Code Playgroud)