2012-02-07 81 views
3

我有這些代碼需要我導出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

回答

5

代碼

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

0

謹慎看多的警告:

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

1

好吧,函數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). 。從我個人的經驗來看,代碼變得易於理解。我得到了一個很好的幻想,即產生的進程必須去找到指定模塊的函數,然後用給定的參數執行。

相關問題