需要我导出Erlang shell中的所有函数吗?

问题描述:

我有这些代码需要我导出Erlang shell中的所有函数吗?

start() -> 
    spawn(?MODULE, init, [self()]). 

init(From) -> 
    spawn(?MODULE, broadcast, []).  

broadcast() -> 
    Msg = "helloworld", 
    timer:sleep(10000), 
    broadcast(). 

当我测试二郎壳这些代码,它给我UNDEF错误,我需要出口播放功能,我只是拒绝

+0

正如您所写,您需要导出'start/0'函数,以便可以调用它和'init/1'函数。当你像spawn/3一样产生一个函数时,那么这个函数也必须被导出。另一种方法是像其他人一样建立一种乐趣。 – rvirding 2012-02-09 22:50:40

代码

spawn(?MODULE, init, [self()]). 

意味着你将产生过程,最初的通话将相当于apply(?MODULE,init,[self()])?MODULE:init(self())或者更精确地。 ?MODULE宏评估为当前模块名称,但无论如何这是外部函数调用,所以这个功能必须导出,即使有?MODULE使用。在相反

spawn(fun() -> init(self()) end). 

中都会产生的FUNC fun() -> init(self()) end与功能self()结果调用init/1初始呼叫。这是本地电话,这意味着init/1可能不会被导出。还有另外一个问题,用它当self()是内部新工艺,所以你必须写

Self = self(), spawn(fun() -> init(Self) end). 

spawn(?MODULE, init, [self()])其中self()作为的spawn/3参数评估,以达到相同的效果而进行的。

+0

好的答案:Self = self(),spawn(fun() - > init(Self)end)。 – why 2012-02-08 02:06:50

谨慎看多的警告:

test.erl:8: Warning: function init/1 is unused 
test.erl:8: Warning: variable 'From' is unused 
test.erl:11: Warning: function broadcast/0 is unused 
test.erl:12: Warning: variable 'Msg' is unused 

编译器认为你的其他函数没有使用,也从不编译它们。试试这个:

start() -> 
    spawn(fun() -> init(self()) end). 

init(From) -> 
    spawn(fun() -> broadcast() end). 
+0

“spawn(?MODULE,broadcast,[])”和“spawn(fun() - > broadcast()end)之间的区别是什么?” ? – why 2012-02-07 10:16:57

好吧,函数broadcast是在一个进程中执行的。因此该功能必须可供所有进程访问。即使同一个模块中的同一段源代码产生了一个从同一个模块执行某个功能的进程,该功能也必须从该模块中导出才能访问。

这将我带到spawn(fun() -> broadcast() end).spawn(?MODULE, broadcast, [])之间的差异。后者称为Spawning with MFA。在这种方法中,该功能必须从模块中导出,以便可以执行。前者是独特的,它的一个fun

要理解这种方法:spawn(fun() -> broadcast() end).,我们需要将它与这一个进行比较:spawn(fun() -> ?MODULE:broadcast() end).。现在,让我们谈谈两个


spawn(fun() -> ?MODULE:broadcast() end).

后来的现在,这里,如果函数 broadcast不会导出模块中: ?MODULE,该进程将崩溃。请注意,在这种情况下,该函数位于编写这段源代码的模块中。
spawn(fun() -> broadcast() end).

在这种情况下,函数必须位于编写这段源代码的模块中。但是,我的想法是,编译器将其转换为上面的代码,以便生成的过程被告知您正在查找的函数位于模块 ?MODULE中。

我不是真正的编译器或运行时系统的大师,但我想你会使用这个答案。我的强烈建议是,在大多数源代码中,即使代码或函数驻留在与此相同的模块中,也使用此 spawn(fun() -> ?MODULE:broadcast() end).spawn(fun() -> some_module:broadcast() end). spawn(fun() -> broadcast() end). 。从我个人的经验来看,代码变得易于理解。我得到了一个很好的幻想,即产生的进程必须去找到指定模块的函数,然后用给定的参数执行。