2009-11-25 58 views
0

我的代碼可以在今年的所有日子裏顯示。爲什麼不init:stop()直接終止?

我不明白爲什麼if NewSec =< EndSec -> init:stop() end沒有在run_calendar中第一次執行?

我希望init:stop()可以被第一次執行,但事實並非如此。
有什麼不對?

代碼:

-module(cal). 
-export([main/0]). 

main() -> 
    StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}), 
    EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}), 
    run_calendar(StartSec,EndSec). 

run_calendar(CurSec, EndSec) -> 
    {Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec), 
    io:format("~p~n", [Date]), 
    NewSec = CurSec + 60*60*24, 
    if NewSec =< EndSec -> init:stop() end, 
    run_calendar(NewSec, EndSec). 

結果:

wk# erlc cal.erl 
wk# erl -noshell -s cal main 
{2009,1,1} 
{2009,1,2} 
{2009,1,3} 
{2009,1,4} 
{2009,1,5} 
... 
{2009,12,22} 
{2009,12,23} 
{2009,12,24} 
{2009,12,25} 
{2009,12,26} 
{2009,12,27} 
{2009,12,28} 
{2009,12,29} 
{2009,12,30} 
{2009,12,31} 
wk# 
+0

爲什麼你不要只是改變如果**不**調用'run_calendar/2'遞歸:'如果NewSec = < EndSec ->好的; true - > run_calendar(NewSec,EndSec)end.',你的程序將正常退出而不會出現奇怪的行爲。 – 2009-11-27 10:07:50

回答

4

我相信初始化:停止()是一個異步的過程,將嘗試順利關停運行。根據the docs,「所有應用程序順利取下,所有代碼都被卸載,所有端口在系統終止前都關閉。」

實際停止可能需要一段時間,因爲您有一個積極運行的過程。如果你改變「的init:停止()」到「退出(停止)」,它會立即終止:

3> cal:main(). 
{2009,1,1} 
** exception exit: stop 
    in function cal:run_calendar/2 
2

初始化:停止是異步的,它需要時間來退出。另一種方法是將包測試中調用本身和使用模式匹配來終止循環:

-module(cal). 
-export([main/0]). 

main() -> 
    StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}), 
    EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}), 
    run_calendar(false, StartSec, EndSec). 

run_calendar(true, _StartSec, _EndSec) -> 
    finished; 

run_calendar(false, CurSec, EndSec) -> 
    {Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec), 
    io:format("~p~n", [Date]), 
    NewSec = CurSec + 60*60*24, 
    run_calendar(NewSec =< EndSec, NewSec, EndSec). 

(或類似的東西,希望你的想法)

+2

即使您有適合目的的免責聲明:「結束」是一個關鍵字,如果您希望它作爲原子,則必須單引號。 – Christian 2009-11-26 11:49:37

+0

是的,我在我的例子中爲null,並認爲在輸出結束會更好。難道我現在已經改變了它 – 2009-11-26 15:35:48

+0

(感謝糾正我) – 2009-11-26 15:38:12

0

你有一個錯誤你的if語句

你說

 
if NewSec =< EndSec -> init:stop() end, 

這是不正確。你必須寫一樣的東西:

 
if 
    A =< B -> do something ...; 
    true -> do something else 
end 

的,如果語法

 
if 
    Condition1 -> Actions1; 
    Condition2 -> Actions2; 
    ... 
end 

這些條件之一必須是真實的。

這是爲什麼?

Erlang是一種功能性語言,而不是語句語言。在功能 語言中,每個表達式都必須有一個值。如果是一個表達式,所以它必須有一個值。

(如果2> 1 - > 3結束)的值爲3,但是 的值(如果1> 2 - > 3結束) - 回答它沒有值 - 但它的值必須爲 一切都必須有價值。

在語句語言中,一切都會因其副作用而被評估 - 因此這將是一個有效的構造。

在Erlang中,您將生成一個異常。

因此,您的代碼會生成一個異常 - 您不會陷入,因此您不會看到它並且 init:stop()永遠不會被調用...

相關問題