2009-11-25 59 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()永远不会被调用...

相关问题