假设我有两个模块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")
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?我对Erlang比较新,不知道怎么做.在Java中,这将是非常明显的,因为您只返回类的新实例.
只需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)
如果变量中有原子,则可以将其用作模块名称.
所以,你可以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/1和some_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这样的事情,这意味着你会在模块声明的行为a和b这样的:
-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)
这意味着像任何模块a和b该声明,他们支持的行为some_behaviour必须定义这些功能,如果他们不这样做,编译器会说出来.此处还定义了参数类型和返回值,用于静态分析等.