Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Import 如何加载实现相同行为的多个模块_Import_Module_Erlang - Fatal编程技术网

Import 如何加载实现相同行为的多个模块

Import 如何加载实现相同行为的多个模块,import,module,erlang,Import,Module,Erlang,我不明白如何使用多个模块,每个模块实现相同的行为,因为我在编译时遇到了这个错误: 函数已从导入 在我的例子中,我有两个模块实现gen_event行为,我正在尝试将它们导入第三个模块中。 每当我试图编译此代码时,都会收到错误消息: -module(mgr). -import(h1,[init/1]). // implements gen_event -import(h2,[init/1]). // implements gen_event 你不能那样做。导入是一个简单的技巧,可以避免编写

我不明白如何使用多个模块,每个模块实现相同的行为,因为我在编译时遇到了这个错误:

函数已从导入

在我的例子中,我有两个模块实现
gen_event
行为,我正在尝试将它们导入第三个模块中。 每当我试图编译此代码时,都会收到错误消息:

-module(mgr).
-import(h1,[init/1]).   // implements gen_event
-import(h2,[init/1]).   // implements gen_event

你不能那样做。导入是一个简单的技巧,可以避免编写函数的完整“定义”。它只对编译器说:当您在这个模块中看到
init(P)
时,替换为
h1:init(P)

因此,不可能导入具有相同名称/arity的多个函数

对于简短的名称,我认为使用import没有任何好处

如果使用长名称的module:function,并且希望缩短代码中的行,则可以改用宏,并且没有限制(但函数名称与:o相同的可能性也很小):

编辑

下一个示例说明了它的工作原理,首先我创建模块mod1,如下所示:

-module (mod1).

-export ([test/1]).

test(P) ->
    case P of 
        1 -> ok;
        2 -> mod2:test()
    end.
我在外壳中测试它:

1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.
4> c(mod2).
{ok,mod2}
5> mod1:test(1).                                   
ok
6> mod1:test(2).                                   
now it works
ok
7> 
mod2创建为:

-module (mod2).

-export ([test/0]).

test() ->
    io:format("now it works~n").
在shell中继续:

1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.
4> c(mod2).
{ok,mod2}
5> mod1:test(1).                                   
ok
6> mod1:test(2).                                   
now it works
ok
7> 
如您所见,无需修改
mod1
,只需创建和编译
mod2
(请注意,如果mod2已经存在,但功能测试/0未导出,则情况相同)


如果要验证代码是否未使用未定义函数,可以使用外部工具。在使用管理项目时,我使用命令rebar3 xref执行此检查。请注意,调用未定义函数是一个简单的警告,在应用程序升级的上下文中它是有意义的。这种验证不是防弹的:它是在构建时完成的,这并不能保证您需要的模块会在生产系统上以正确的版本出现:它打开了许多关于版本控制、代码加载……的有趣问题。

此外,本地函数包装对远程的调用;如果经常使用,可能会从中进行后端口。我认为,当您
导入
时,您也会编译
导入的
模块,因此您可以一箭双雕(语言简洁+编译)。因此,如果我的模块
Parent
使用了另一个模块
Child
我不需要导入它,我可以调用
Child:method()
(如果我事先编译
)?编译中没有顺序。调用在运行时解决:如果被调用的模块没有加载到VM中,它将首先加载它,然后它将查找函数。如果存在,很好,它将执行调用;如果它不存在,然后它将在执行过程中失败。但在我的例子中,问题是我不是使用
init
的人。在我的例子中,init被
gen\u事件:add\u handler
方法使用。库代码期望目标模块中有
init
。在我的例子中,我有多个模块实现
gen\u事件
行为,它们都需要公开
init
。好的,我在以前的项目中做过这件事,我将尝试检索这个示例并提出一个简化版本。