如何在Erlang中动态调用模块?

时间:2016-01-03 16:51:22

标签: erlang

假设我有两个模块 a.erl b.erl 。两个模块都包含相同的功能(在Java中我会说“两个类都实现相同的接口”)。 在模块“c.erl”中我想要一个将返回模块“a”或“b”的函数(取决于参数)

以下是我希望在 c.erl

模块中使用的内容
-module(c)

get_handler(Id) ->

 % if Id == "a" return a

 % if Id == "b" return b

test() ->

 get_handler("a"):some_function1("here were go for a"),

 get_handler("a"):some_function2("aaaa"),

 get_handler("b"):some_function1("here we go for b")

我该如何使这项工作?我对Erlang比较新,不知道怎么做。在Java中,这将非常明显,因为您只需返回该类的新实例。

2 个答案:

答案 0 :(得分:7)

get_handler/1将模块名称作为原子返回,然后用它来调用所需的函数:

(get_handler("a")):some_function2("aaaa"),
(get_handler("b")):some_function1("here we go for b").

请注意,在这种情况下,您需要围绕get_handler/1的调用括号。

模块get_handler/1a的简单版b可以是:

get_handler("a") -> a;
get_handler("b") -> b.

答案 1 :(得分:5)

如果变量中有原子,则可以将其用作模块名称。

因此,您可以像这样定义c:get_handler/1

get_handler("a") -> a;
get_handler("b") -> b.

你的c:test/0看起来不错,除非你需要额外的括号,如下所示:

test() ->
    (get_handler("a")):some_function1("here were go for a"),
    (get_handler("a")):some_function2("aaaa"),
    (get_handler("b")):some_function1("here we go for b").

然后在模块ab中,只需定义some_function1/1some_function/2,例如:

some_function1(Str) ->
    io:format("module ~s function some_function1 string ~s~n", [?MODULE, Str]).

some_function2(Str) ->
    io:format("module ~s function some_function2 string ~s~n", [?MODULE, Str]).

编辑:如果你要做BTW这样的事情你也应该定义一个行为,这意味着你会在模块a和{{1}中声明这样的事情:

b

然后创建模块-behaviour(some_behaviour). ,如下所示:

some_behaviour

这意味着任何模块如-module(some_behaviour). -callback some_function1 (String :: string()) -> ok . -callback some_function2 (String :: string()) -> ok . a声明它们支持行为b必须定义这些函数,如果不这样做,编译器会说出来。此处还定义了参数类型和返回值,用于静态分析等。