我是新來的Erlang,但在這裏就是我想這些東西是什麼,他們之間的分歧,他們已經習慣什麼,等:
throw
:應該在本地處理的條件(即在當前的過程中)。例如。調用者正在查找集合中的元素,但不知道集合是否實際上包含這樣的元素;然後,如果這樣的元素不存在,則被叫者可能會拋出,並且呼叫者通過使用try[/of]/catch
來檢測缺席。如果主叫方忽略這樣做,那麼這會變成一個nocatch
error
(解釋如下)。
exit
:當前過程完成。例如。它會簡單地完成(在這種情況下,您將通過normal
,這與返回的原始函數相同),或者其操作被取消(例如,它通常無限期地循環但剛剛收到shut_down
消息)。
error
:進程已經完成了一些事情並且/或者達到了程序員沒有考慮到的狀態(例如1/0),認爲不可能(例如case ... of
遇到與任何情況都不匹配的值),或者某些先決條件未得到滿足(例如輸入不爲空)。在這種情況下,本地恢復是沒有意義的。因此,throw
和exit
都不合適。由於這是意想不到的,堆棧跟蹤是原因的一部分。
正如你所看到的,上面的清單是爲了升級:
throw
是主叫方,預計處理理智的條件。即處理髮生在內當前的過程。
exit
也是理智的,但應該因爲過程完成而結束當前過程。
error
是瘋了。發生了一些無法合理恢復的事情(通常是一個錯誤?),並且本地恢復不合適。
與其他語言:
throw
類似的方式檢查異常在Java中使用。而error
的使用方式更類似於未經檢查的例外情況。檢查異常是您希望調用者處理的異常。 Java要求你在try/catch
中打包調用,或者聲明你的方法throws
這樣的例外。而未檢查的異常通常會傳播到最外面的調用者。
exit
沒有像Java,C++,Python和JavaScript中,紅寶石等exit
依稀像一個uber- return
更「傳統」的語言好的模擬:而不是在端返回,可以從返回一個函數的中間,除了你不只是從當前函數返回,你從它們全部返回。
exit
例
serve_good_times() ->
receive
{top_of_the_mornin, Sender} ->
Sender ! and_the_rest_of_the_day_to_yourself;
{you_suck, Sender} ->
Sender ! take_a_chill_pill;
% More cases...
shut_down ->
exit(normal)
end,
serve_good_times()
end
由於serve_good_times
電話後,自己幾乎所有的消息,程序員已經決定,我們不希望在每個接收的情況下重複這一呼籲。因此,她在收到後已撥打。但是,如果serve_good_times
決定停止調用自己呢?這是exit
來救援。將normal
傳遞給exit
會導致進程終止,就像上次函數調用已返回一樣。
因此,通常不宜在通用庫中調用exit
,如lists
。這個過程是否應該結束,這不是圖書館的業務;這應該由應用程序代碼決定。
異常怎麼樣exit
?
這一點很重要,如果另一個進程(「遠程」的過程)鏈接到「本地」過程調用exit
(和process_flag(trap_exit, true)
不叫):就像過去的函數返回時,exit(normal)
不會導致遠程進程退出。但是如果本地進程撥打exit(herp_derp)
,那麼遠程進程也會以Reason=herp_derp
退出。當然,如果遠程進程鏈接到更多進程,他們也會通過Reason=herp_derp
獲得退出信號。因此,不存在導致連鎖反應。
讓我們來看看這個動作:
1> self().
<0.32.0>
2> spawn_link(fun() -> exit(normal) end).
<0.35.0>
3> self().
<0.32.0>
4>
4>
4> spawn_link(fun() -> exit(abnormal) end).
** exception exit: abnormal
5> self().
<0.39.0>
6>
,我們產生了沒有造成shell退出(可以告訴我們,因爲self
之前和spawn_link
後返回相同PID)的第一個過程。但是第二個進程確實導致了shell退出(並且系統用一個新進程替換了shell進程)。
當然,如果遠程進程使用process_flag(trap_exit, true)
那麼它只會得到一條消息,無論本地進程是通過normal
還是別的通過exit
。設置這個標誌可以停止連鎖反應。
6> process_flag(trap_exit, true).
false
7> spawn_link(fun() -> exit(normal) end).
<0.43.0>
8> self().
<0.39.0>
9> flush().
Shell got {'EXIT',<0.43.0>,normal}
ok
10>
10>
10> spawn_link(fun() -> exit(abnormal) end).
<0.47.0>
11> self().
<0.39.0>
12> flush().
Shell got {'EXIT',<0.47.0>,abnormal}
回想一下,我說的是exit(normal)
像原來的函數返回處理:
13> spawn_link(fun() -> ok end).
<0.51.0>
14> flush().
Shell got {'EXIT',<0.51.0>,normal}
ok
15> self().
<0.39.0>
你知道些什麼:同樣的事情發生當exit(normal)
被調用。精彩!
非常感謝您的幫助。現在更清楚了。 –
@ChenYu - 爲我的草率解釋道歉。 rvirding - 謝謝你清理那個。讓我修復/刪除我的答案 - 更好的混淆! – Faiz