@JackAidley가 이미 그 요점을 말했다고 생각 하지만 다음과 같이 공식화하겠습니다.
예외없이 (예 : C)
규칙적인 코드 흐름에는 다음이 있습니다.
if (condition) {
statement;
} else if (less_likely_condition) {
less_likely_statement;
} else {
least_likely_statement;
}
more_statements;
"초기 오류"사례에서 코드는 갑자기 다음과 같이 읽습니다.
/* demonstration example, do NOT code like this */
if (condition) {
statement;
} else {
error_handling;
return;
}
이 패턴을 발견하는 경우 - a는 return
에 else
(또는 if
문제의 코드는 않도록) 블록, 즉시 재 작업 하지 이 else
블록 :
/* only code like this at University, to please structured programming professors */
function foo {
if (condition) {
lots_of_statements;
}
return;
}
현실 세계에서…
/* code like this instead */
if (!condition) {
error_handling;
return;
}
lots_of_statements;
이것은 너무 깊이 중첩 방지 및 은 "초기 탈옥"경우 (마음을 유지하는 데 도움이 -하고 코드 흐름 - 청소)을 충족 하고 (가) "는에 가능성이 일을 넣어 위반하지 않는 if
단순히 어떤이 없기 때문에 일부" else
부분 .
C
정리
비슷한 질문에 대한 답변에서 영감을 얻었습니다 (이 잘못됨). C로 정리하는 방법은 다음과 같습니다. 하나 또는 두 개의 출구 지점을 사용할 수 있습니다. 여기에는 두 개의 출구 지점이 있습니다.
struct foo *
alloc_and_init(size_t arg1, int arg2)
{
struct foo *res;
if (!(res = calloc(sizeof(struct foo), 1)))
return (NULL);
if (foo_init1(res, arg1))
goto err;
res.arg1_inited = true;
if (foo_init2(&(res->blah), arg2))
goto err;
foo_init_complete(res);
return (res);
err:
/* safe because we use calloc and false == 0 */
if (res.arg1_inited)
foo_dispose1(res);
free(res);
return (NULL);
}
정리가 덜 필요한 경우 하나의 종료점으로 축소 할 수 있습니다.
char *
NULL_safe_strdup(const char *arg)
{
char *res = NULL;
if (arg == NULL)
goto out;
/* imagine more lines here */
res = strdup(arg);
out:
return (res);
}
goto
당신이 그것을 다룰 수 있다면, 이 사용 은 완벽하게 좋습니다. 사용 goto
하지 않는 것이 좋은지, 수용 가능한지, 나쁜지, 스파게티 코드 등을 스스로 결정할 수없는 사람들을 대상으로합니다.
예외
위의 예외는 예외없이 언어에 대해 이야기하며, 나는 나 자신을 선호합니다 (명시 적 오류 처리를 훨씬 잘하고 훨씬 덜 놀라게 사용할 수 있습니다). igli를 인용하려면 :
<igli> exceptions: a truly awful implementation of quite a nice idea.
<igli> just about the worst way you could do something like that, afaic.
<igli> it's like anti-design.
<mirabilos> that too… may I quote you on that?
<igli> sure, tho i doubt anyone will listen ;)
그러나 예외가있는 언어로 잘 사용하는 방법과 잘 사용하고 싶을 때의 제안은 다음과 같습니다.
예외 상황에서 오류 반환
초기 return
의 대부분을 예외를 던지는 것으로 바꿀 수 있습니다 . 그러나 , 귀하의 일반적인 코드의 흐름 즉, 프로그램의 흐름이있는 프로그램은 물론, 예외 ... 오류 상태가 발생하거나 somesuch하지 않습니다 예외를 올립니다.
이것은…
# this page is only available to logged-in users
if not isLoggedIn():
# this is Python 2.5 style; insert your favourite raise/throw here
raise "eh?"
… 괜찮지 만…
/* do not code like this! */
try {
openFile(xyz, "rw");
} catch (LockedException e) {
return "file is locked";
}
closeFile(xyz);
return "file is not locked";
… 아니다. 기본적으로 예외는 제어 흐름 요소가 아닙니다 . 또한, "자바 프로그래머는 항상 이러한 예외가 정상이라고 알려주는"조작이 이상하게 보이고 디버깅을 방해 할 수 있습니다 (예 : IDE가 예외를 중단하도록 지시). 예외는 종종 스택 백을 해제하기 위해 스택을 풀기 위해 런타임 환경을 요구합니다. 이에 대한 더 많은 이유가있을 수 있습니다.
예외를 지원하는 언어에서는 기존 논리 및 스타일과 일치하고 자연스럽게 느껴지는 것을 사용하십시오. 처음부터 무언가를 작성하는 경우 조기에 동의하십시오. 라이브러리를 처음부터 작성하는 경우 소비자를 생각하십시오. ( abort()
도서관 에서도 사용하지 마십시오 .) 그러나 무엇을하든 일반적으로 그 이후에 작업이 정상적으로 계속되는 경우 예외가 발생하지 않습니다.
일반적인 조언 wrt. 예외
전체 개발자 팀이 먼저 합의한 예외를 프로그램 내에서 모두 사용하도록하십시오. 기본적으로 계획하십시오. 그것들을 풍부하게 사용하지 마십시오. 때로는 C ++, Java ™, Python에서도 오류 리턴이 더 좋습니다. 때로는 그렇지 않습니다. 생각과 함께 사용하십시오.