2009-11-25 3 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

if를'not not ** 'run_calendar/2를 재귀 적으로 호출하는 것이 어떨까요?'If NewSec = < EndSec -> ok; true -> run_calendar (NewSec, EndSec) end.' 그리고 당신의 프로그램은 기발한 행동없이 정상적으로 종료 될 것입니다. –

답변

4

내가 그 초기화 믿습니다. the docs에 따르면 "모든 응용 프로그램이 원활하게 중단되고 모든 코드가 언로드되며 시스템이 종료되기 전에 모든 포트가 닫힙니다."

실제로 실행중인 프로세스가 있기 때문에 실제로 중지하는 데 시간이 걸릴 수 있습니다. 당신이 변경하면 정지가 비동기과 종료 시간이 걸릴 것입니다 :

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

+0

예, 필자의 예에서 null이 발생했으며 출력이 더 좋을 것이라고 생각했습니다. 나 지금 바꿨어? –

+0

(고맙다.) –

0

당신은 실수에 있습니다 또 다른 방법은 전화 자체 테스트를 마무리하고 루프를 종료하는 패턴 매칭을 사용하는 것입니다 당신의 문

경우 이것은 잘못된

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

말했다. 구문은 이러한 조건의

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

하나는 항상 참이어야합니다

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

: 당신은 뭔가를 작성해야합니다.

왜 이런가요?

Erlang은 명령 언어가 아닌 기능 언어입니다. 함수 언어에는 모든 표현식에 값이 있어야합니다. if는 표현식이므로 값을 가져야합니다.

(2> 1 -> 3 일 경우) 값은 3이지만, (1> 2 -> 3 끝일 경우) 값은 무엇이겠습니까? 대답에는 값이 없지만 값은 이어야합니다. 모든 것은 가치가 있어야합니다.

문언 언어에서는 모든 것이 부작용으로 평가됩니다. 따라서 이 유효합니다.

얼랑 (Erlang)에서는 예외가 발생합니다.

그래서 코드가 예외를 생성합니다. 당신이 함정에 빠지지 않도록하고 init : stop()은 결코 호출되지 않습니다 ...

관련 문제