在Erlang中,如何动态调用函数?

wbgh16ku  于 2022-12-08  发布在  Erlang
关注(0)|答案(5)|浏览(205)

我想用要调用的函数名来调用xyz。

-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>
91zkwejq

91zkwejq1#

必须导出p和g是正确的。然后可以使用apply/3调用它。

erlang:apply(sample, p, []).

只有函数值可用于Fun(...)语法。您正在传入原子值。原子是错误消息中的“错误函数”。您可以执行类似于

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

那就打电话给我

Fun = xyz(p),
Fun()
gzjq41n4

gzjq41n42#

-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"
4dbbbstv

4dbbbstv3#

Pattern match is the idiom to use:

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

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

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

If you want to be dynamic you can use a gen_event server.
Essentially what this is is a server that holds a state which consists of key/function pair like so:

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

You can then essentially bind events to functions. (there is, needless to say, a bit more to it than that.

laik7k3q

laik7k3q4#

最简单的方法是尝试将p和g与xyz一起导出。

-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"
h9vpoimq

h9vpoimq5#

换个Angular 来看(取决于你要解决的问题)动态调用函数并不一定是正确的方法。由于Erlang是一种“面向并发的语言”,所以进程和消息传递是你在Erlang中组织代码的方式,也许您可以只使用消息传递和选择性接收器,而不是模仿顺序语言习惯用法?发送一条你想要的消息,然后得到基于此的自定义回复。这是关于每个函数的结果,而不是函数本身。(另外还有消息传递的灵活性和可伸缩性等。)
虽然进程与从库模块调用相比不是完全免费的,但Erlang级别的进程非常便宜(特别是当消息通信在同一个节点内时)。它们不是操作系统级别的进程。其开销相当于(或优于)较重的脚本语言中的动态函数调用和对象示例化。

相关问题