【问题标题】:How to call a module dynamically in Erlang?如何在 Erlang 中动态调用模块?
【发布时间】:2016-01-04 01:56:00
【问题描述】:

假设我有两个模块 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")

我怎样才能做到这一点?我对 Erlang 比较陌生,不知道该怎么做。在 Java 中这很明显,因为您只需返回该类的新实例。

【问题讨论】:

  • 我不确定我是否理解这个问题的写法。你会不会直接导入:-import(Module, [Function1/Arity, ..., FunctionN/Arity]).,然后调用a:some_function/arityb:some_function/arity
  • 我不想在模块“c”或“if”语句中有不同的调用。我想要调用函数的相同代码取决于 get_handler 返回的内容。在我的示例中,get_handler 在“a”和“b”之间进行选择,但它可以选择的模块可能更多。

标签: erlang


【解决方案1】:

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

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

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

get_handler/1 模块 ab 的简单版本可以是:

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

【讨论】:

  • 非常感谢您的回答。这正是我需要的。我的问题已解决。
【解决方案2】:

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

所以,你可以这样定义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]).

编辑: 如果你要做这种事情顺便说一句,你可能还应该定义一个行为,这意味着你会在模块 ab 中声明类似这样的东西:

-behaviour(some_behaviour).

然后创建模块some_behaviour 像这样:

-module(some_behaviour).
-callback some_function1 (String :: string()) -> ok .
-callback some_function2 (String :: string()) -> ok .

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

【讨论】:

  • 非常感谢您的回答。这正是我需要的。我的问题已解决。
猜你喜欢
  • 2010-11-21
  • 2016-10-20
  • 2018-08-28
  • 2011-02-23
  • 2012-10-24
  • 2013-01-22
  • 1970-01-01
  • 2010-12-09
  • 2013-03-27
相关资源
最近更新 更多