在二郎,你如何动态调用一个函数?(In Erlang, how do you invoke a fu

2019-08-02 00:57发布

我想打电话给某某与被调用的函数的名称。

-module(sample).
-export([xyz/1]).

xyz(Name) -> Name().

p() -> "you called p".
g() -> "you called g".

但我得到以下错误:

1> c(sample.erl).
./sample.erl:6: Warning: function p/0 is unused
./sample.erl:7: Warning: function g/0 is unused
{ok,sample}
2> sample:xyz('p').
** exception error: bad function p
     in function  sample:xyz/1
3>

Answer 1:

It is correct that you have to export p and g. You can then use apply/3 to call it.

erlang:apply(sample, p, [])

Only fun-values are usable with the Fun(...) syntax. You are passing in an atom-value. An atom is a 'bad function' as the error message go. You could do something similar to

xyz(p) -> fun p/0;
xyz(g) -> fun g/0.

Then go ahead and call

Fun = xyz(p),
Fun()


Answer 2:

-module(sample).
-export([xyz/1, p/0, g/0]).

xyz(Name) -> ?MODULE:Name().

p() -> "you called p".
g() -> "you called g".


1> sample:xyz(p).
"you called p"


Answer 3:

模式匹配是使用成语:

-module(sample).
-export([xyz/1]).

xyz(p) -> p();
xyz(q) -> g().

p() -> "you called p".
g() -> "you called g".

如果你想成为动态的,你可以使用一个gen_event服务器。

从本质上讲这是什么是持有其中包括键/功能对像这样的状态的服务器:

[{p, #func1},
 {g, #func2},
 {..., ...},
 ...]

然后,您可以基本事件绑定到的功能。 (有,不用说,更给它一点比。



Answer 4:

做最简单的方法是尝试与XYZ沿着出口P和G。

-export([xyz/1, p/0,g/0]).

导出函数p和g之后可以被称为如下:

1> sample:xyz(fun sample:p/0).
"you called p"
2> sample:xyz(fun sample:g/0).
"you called g"


Answer 5:

看它的另一种方式是(取决于你解决问题),动态调用函数的不一定是正确的做法。 由于流程和消息传递是你组织你的代码在二郎山,因为这是一个“面向并发语言”的方式,也许你可以只使用消息选择性接收传递,而不是模仿顺序语言的成语? 发送一条消息给你想要的东西,并获得基于的自定义回复。 这是关于每个函数,而不是函数本身,毕竟结果。 (加有灵活性和消息传递的可扩展性等)

虽然过程不是完全自由的与从一个库模块调用,二郎级进程是非常便宜(尤其是如果该消息通信是同一节点内)。 他们不是OS级别进程。 开销将是相当(或更好),以较重的脚本语言动态函数调用和对象实例化。



文章来源: In Erlang, how do you invoke a function dynamically?
标签: erlang