항상 이와 같은 것을 찾아야합니다.
귀하의 코드는 귀하가 생각하는대로하지 않습니다.
-module(glurk).
-compile(export_all).
fn2() ->
try
{ok, Result} = fn1(),
%Do something with Result
ok
catch
throw:Term -> Term;
exit:Reason -> {exit, Reason};
error:Reason -> {error,{Reason,erlang:get_stacktrace()}}
end.
fn1() ->
{error, a}.
이 밖으로 시도 :을 Fn1 예외 를 제기하지 않았기 때문에
c(glurk).
./glurk.erl:6: Warning: variable 'Result' is unused
{ok,glurk}
16> glurk:fn2().
{error,{{badmatch,{error,a}},
[{glurk,fn2,0},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_exprs,6},
{shell,eval_loop,3}]}}
이 그것을 gebnerated되는 일반 retyurn 값 {오류, A}에 대해 패턴 일치를하지 않는 {확인, 결과 }
코드의 첫 번째 버전 중 하나를 정상적인 값 을 반환하거나 예외를 발생시키는 기능을 작동 -이처럼 작성해야 :
fn1(....) ->
...
%% success case
Val;
%% failure case
throw(...) | exit(...) | error(...)
동일한 기능을 fn1 및 fn2로 펌핑 할 수 없습니다.
당신이 호출 된 함수가 다음 첫 번째 방법은 두 번째보다 더 효율적으로 될 것입니다 깊은 재귀 에서 탈출했다 경우이 있다면 - 당신이 (던져 말함으로써 깊은 재귀에서 즉시 종료를 수 있기를 ...).
따라서 대답은 사용자가 호출하는 기능의 성격에 따라 다릅니다.
코드는 아름다움을 유지하면서 효율적으로 최적화되지 않아야합니다. 코드를 유지 관리하려면 이 있어야합니다. 그렇기 때문에 드문 경우에만 에 최적화해야합니다. 무슨 일이, 내가 실제로 첫 번째 코드는 더 미묘한 오류가
{ok,Result} = ...
써서 프로그램 (당신은 항상
나를 :-) 여기에 놀라게 될 것입니다을 측정하여 확인되어야한다 최적화 할 필요가
fn2() ->
try
{ok, Result} = fn1(),
%Do something with Result
ok
catch
throw:Term -> Term;
exit:Reason -> {exit, Reason};
error:Reason -> {error,{Reason,erlang:get_stacktrace()}}
end.
이것에 대해 생각해보십시오. 잡힌 오류 사례 자체는 오류를 처리하지 않습니다. {exit, Reason} 또는 {Error, Reason}과 같은 튜플을 반환합니다. 즉, 다음 계층 (즉 fn2의 호출자)도 을 확인해야합니다. 오류가 반환됩니다 - 모든 레벨에서 반복되는 경우 코드가 엉망이됩니다.
"erlang"방법은 프로그램 상단에 하나의 try-catch를 두어 오류가 발생하면 갑자기 exit (이유)를 사용하여 종료합니다.
사실 종종이 작업을 수행해서는 안됩니다. 프로세스를 다른 프로세스 에 연결해야합니다. 그러면 문제가되는 프로세스가 종료되고 "다른 프로세스가 오류를 수정합니다".
예외는 호출 스택을 전파하고 처리를 위해 연결된 프로세스 으로 이동합니다. 따라서 두 가지 유형의 프로세스가 있습니다. 즉, 내장 된 오류 처리가없는 프로세스와 오류 처리 만 수행하는 프로세스가 있습니다.
감사합니다, 즉 계몽이었다! :) – ErJab