어설 션을 사용하고 예외를 던지나요?


38

종종 함수를 작성할 때 가능한 한 빨리 그러한 오류를 감지하기 위해 입력이 유효한지 확인하고 싶습니다 (사전 조건이라고 부릅니다). 전제 조건이 실패하면 항상 예외가 발생했습니다. 그러나 이것이 최선의 방법인지 아닌지에 대한 의문이 제기되고 있습니다.

따라서 언제해야합니까 : 어설 션을 사용하는 것이 적절한시기와 예외를 던지는 것이 적절한시기는 언제입니까?


3
나는이 질문이 stackoverflow에 대해 질문되어야한다고 생각하지만, 아마도 거기에 수십 번 묻었을 것이므로 이미 많은 답변을 찾을 수 있습니다.
user281377

답변:


50

어설 션은 논리적으로 거짓이 될 수 없는 조건을 확인하는 데만 사용해야합니다 (읽기 : 온 전성 검사). 이러한 조건은 자신의 코드로 생성 된 입력을 기반으로해야합니다. 외부 입력을 기반으로하는 모든 검사는 예외를 사용해야합니다.

내가 따르는 경향이있는 간단한 규칙은 assert를 사용하여 개인 함수의 인수를 확인하고 공개 / 보호 함수의 인수에 예외를 사용하는 것입니다.


외부 입력에 예외를 사용하는 것에 대한 좋은 지적. 또한 파일 / 데이터베이스 등에 작성 / 쓰기를 시도 할 때 발생하는 문제도 출력에 추가합니다.
ChrisF

13
그리고 필연적으로 이러한 주장이 생산 과정에서 시작되는 것을 보게 될 것입니다. 어설 션으로 개인 정보 를 확인하는 +1 ! "입력을 완전히 제어 할 때 어설 션 사용"이라고 말할 수 있습니까?
Frank Shearar

1
Java에서는 최소한 -ea 명령 줄 매개 변수를 사용하여 어설 션 검사를 활성화해야합니다. 즉, 명시 적으로 설정하지 않으면 어설 션이 효과적으로 작동하지 않습니다.
Bill Michell

29

어설 션은 프로그래밍 오류를 찾는 데 사용됩니다. 모든 어설 션이 제거 될 때도 프로그램이 제대로 작동해야합니다.

반면에 예외는 프로그램이 완벽 할 때 발생할 수있는 상황에 대한 것입니다. 하드웨어, 네트워크, 사용자 등과 같은 외부 영향으로 인해 발생합니다.


이것은 꽤 좋은 방법입니다. 사용자가 잘못된 것을 입력하면 예외를 던집니다. 입력이 정확하지만 여전히 잘못된 경우 어설 션을 던집니다.
Mateen Ulhaq

3

일반적인 프로그래밍 실습은 프로덕션 / 릴리스 빌드에서 어설 션을 컴파일하는 것입니다. 어설 션은 내부 테스트 중에 만 가정의 실패를 포착하는 데 도움이됩니다. 외부 대행사의 행동을 취해서는 안되므로 네트워크 또는 사용자의 이벤트를 주장해서는 안됩니다. 또한 어설 션이 실패 할 경우 프로덕션 빌드를위한 처리 코드를 작성하는 것이 좋습니다.

예를 들어 C에서는

int printf(const char *fmt, ...)
{
  assert(fmt);  // may fail in debug build but not in production build
  if (!fmt) return -1; // handle gracefully in production build
  ...
}

프로덕션 빌드에는 예외가 있습니다. 예외의 대안은 어설 션이 아닌 오류를 반환하는 것입니다.


2
나는 같은 조건에 대한 주장 뒤에 우아한 행동을하는 것이 좋은 생각이라고 생각하지 않습니다. 필연적으로, 정상적인 동작은 프로덕션 버전에만 존재하기 때문에, 정상적인 동작을 처리해야하는 코드는 제대로 테스트되지 않았으며 코드가 보호되지 않았을 때와 마찬가지로 나쁘게 충돌합니다.
Sebastian Redl

0

나를 위해 주장하는 한 가지 문제는 Java에서 기본적으로 비활성화되어 있다는 것입니다.

우리는 몇 년 동안 무인으로 실행되었던 프로그램이 예상치 못한 형태로 나쁜 데이터의 경우 데이터 손상을 피하기 위해 가능한 빨리 충돌해야하는 실패 우선 전략을 사용합니다. 이것이 우리가 검사를 사용하는 것이며, assert를 사용하면 기본적으로 활성화되지 않을 위험이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.