繁体   English   中英

如何通过指定模块和方法名称在Elixir中动态调用方法?

[英]How to call a method dynamically in Elixir, by specifying both module and method name?

我想知道elixir中的方法名称究竟是什么:

array = [1,2,3]
module_name = :lists
method_name = :nth                  # this not working
module_name.method_name(1, array)   # error, undef function lists.method_name/2
module_name.nth(1, array)           # returns 1, module_name is OK. It's an atom

但我可以在erlang中做同样的事情:

A = [1,2,3].
X = lists.
Y = nth.
X:Y(1,A).  #  returns 1

我怎么能在灵药中做到这一点?

您可以使用apply/3 ,它只是一个包装器:erlang.apply/3 它只是使用arguments数组从module调用给定的function 由于您将参数作为模块和函数名称传递,因此可以使用变量。

apply(:lists, :nth, [1, [1,2,3]])
apply(module_name, method_name, [1, array])

如果你想更多地了解elixir如何处理函数调用(以及其他所有内容),你应该看一下quoteunquote

contents = quote do: unquote(module_name).unquote(method_name)(1, unquote(array))

它返回函数调用的homoiconic表示。

{{:.,0,[:lists,:nth]},0,[1,[1,2,3]]}

您可以unquote所引用的函数调用Code.eval_quoted/3

{value, binding} = Code.eval_quoted(contents)

编辑:这是一个使用Enum.fetch和var的例子。

quoted_fetch = quote do: Enum.fetch([1,2,3], var!(item));             
{value, binding} = Code.eval_quoted(quoted_fetch, [item: 2])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM