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

cac*_*tus 5 erlang

假设我有两个模块a.erlb.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")
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我对Erlang比较新,不知道怎么做.在Java中,这将是非常明显的,因为您只返回类的新实例.

Ste*_*ski 8

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

(get_handler("a")):some_function2("aaaa"),
(get_handler("b")):some_function1("here we go for b").
Run Code Online (Sandbox Code Playgroud)

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

一个简单的版本get_handler/1的模块a,并b可能是:

get_handler("a") -> a;
get_handler("b") -> b.
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 5

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

所以,你可以c:get_handler/1像这样定义:

get_handler("a") -> a;
get_handler("b") -> b.
Run Code Online (Sandbox Code Playgroud)

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").
Run Code Online (Sandbox Code Playgroud)

然后在模块中a,b只需定义一个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]).
Run Code Online (Sandbox Code Playgroud)

编辑:你应该也可能定义,如果你打算做BTW这样的事情,这意味着你会在模块声明的行为ab这样的:

-behaviour(some_behaviour).
Run Code Online (Sandbox Code Playgroud)

然后创建这样的模块some_behaviour:

-module(some_behaviour).
-callback some_function1 (String :: string()) -> ok .
-callback some_function2 (String :: string()) -> ok .
Run Code Online (Sandbox Code Playgroud)

这意味着像任何模块ab该声明,他们支持的行为some_behaviour必须定义这些功能,如果他们不这样做,编译器会说出来.此处还定义了参数类型和返回值,用于静态分析等.