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

使用元组作为Elixir中函数的参数,elixir,argument-unpacking,Elixir,Argument Unpacking,我正在用长生不老药写一个游戏引擎。(是的,我知道这不是一种天生适合这种情况的语言——重点是看看非典型语言的使用如何影响结果的结构。) 因此,我有几个主管在游戏开始时运行——但他们应该具体负责什么取决于游戏。我的想法是让用户在config.exs文件中列出必要的子元素,加上参数和选项,作为元组列表,然后主管自己只需从应用程序环境中提取这些元组,并将其内容用作worker\2(或worker\3,视情况而定) 但是,我找不到任何与Python的元组解包等效的长生不老药。我可以自己使用一个简单的函数来

我正在用长生不老药写一个游戏引擎。(是的,我知道这不是一种天生适合这种情况的语言——重点是看看非典型语言的使用如何影响结果的结构。)

因此,我有几个主管在游戏开始时运行——但他们应该具体负责什么取决于游戏。我的想法是让用户在
config.exs
文件中列出必要的子元素,加上参数和选项,作为元组列表,然后主管自己只需从应用程序环境中提取这些元组,并将其内容用作
worker\2
(或
worker\3
,视情况而定)

但是,我找不到任何与Python的元组解包等效的长生不老药。我可以自己使用一个简单的函数来完成此特定情况:

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

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

但这充其量感觉很笨拙,而且对于我可能需要这种可配置性的每个函数都必须重新编写。

我认为您需要知道元组的大小才能正确访问元素。对于您的用例来说,更好的数据结构可能是关键字列表,特别是考虑到它是从confi获得的还是g?然后您可以解包worker:,args:,并将其余部分保留为选项?

我相信您将需要和函数的组合

iex(1)> a = {:foo, :bar, :baz}
{:foo, :bar, :baz}
iex(2)> tuple_size(a)
3
iex(3)> elem(a, 0)
:foo
iex(4)> elem(a, 5)
** (ArgumentError) argument error
    :erlang.element(6, {:foo, :bar, :baz})

请注意,如果您在元组中不存在的索引处请求一个元素,您确实会得到一个参数错误。这意味着您仍然必须使用
if
/
case
/
cond
/多个函数头或其他东西来区分您试图执行的操作。

我相信您正在寻找<代码>元组。到列表/1和
应用/3

通过这些,您可以根据元组的内容调用具有正确arity的函数:

def unpack_worker(args) do
  apply(__MODULE__, :worker, Tuple.to_list(args))
end
如果您现在调用
unpack\u-worker({})
,它将调用
worker()
unpack\u-worker({:foo})
将调用
worker(:foo)
,依此类推

演示:

输出:

0
1
2
3
0
1
2
3