신속한 "전제 조건"과 "어설 션"의 차이점은 무엇입니까?


105

precondition(condition: Bool, message: String)assert(condition: Bool, message: String)스위프트 의 차이점은 무엇입니까 ?

둘 다 나에게 똑같아 보인다. 어떤 맥락에서 우리는 다른 것을 사용해야합니까?

답변:


125

assert테스트 중 온 전성 검사를 precondition위한 것이고, 만약 발생하면 프로그램이 합리적으로 진행할 수 없다는 것을 의미하는 일들로부터 보호하기위한 것입니다.

예를 들어, assert버그가 있는지 빠르게 찾기 위해 합리적인 결과 (예 : 일부 범위 내)를 갖는 계산을 할 수 있습니다. 그러나 범위를 벗어난 결과 유효 할 수 있고 중요하지 않을 수 있으므로 앱을 중단해서는 안됩니다 (진행률 표시 줄에 진행률을 표시하는 데 사용하고 있었다고 가정 해 보겠습니다).

반면에 요소를 가져올 때 배열의 첨자가 유효한지 확인하는 것은 precondition. 선택적 값이 아닌 값을 반환 해야 하므로 유효하지 않은 첨자를 요청할 때 배열 객체가 취할 적절한 다음 조치가 없습니다 .

문서의 전체 텍스트 (옵션 클릭 assertpreconditionXcode에서 시도 ) :

전제 조건

앞으로 진행하기 위해 필요한 조건을 확인하십시오.

이 기능을 사용하여 배송 코드에서도 프로그램이 진행되지 않도록해야하는 조건을 감지합니다.

  • 플레이 그라운드 및 -Onone 빌드 (Xcode의 디버그 구성에 대한 기본값) : conditionfalse로 평가 되면 인쇄 후 디버깅 가능한 상태에서 프로그램 실행을 중지합니다 message.

  • -O 빌드에서 (Xcode의 릴리스 구성에 대한 기본값) : conditionfalse로 평가 되면 프로그램 실행을 중지합니다.

  • -Ounchecked 빌드에서 condition평가되지 않지만, 최적화가 있다고 가정 할 수 있습니다 으로 평가 true. -Ounchecked 빌드에서 이러한 가정을 충족하지 못하는 것은 심각한 프로그래밍 오류입니다.

주장

선택적 메시지가있는 전통적인 C 스타일 어설 션입니다.

테스트 중에 활성화되지만 배송 코드의 성능에 영향을주지 않는 내부 온 전성 검사에이 기능을 사용합니다. 릴리스 빌드에서 잘못된 사용을 확인하려면 참조하십시오 precondition.

  • 플레이 그라운드 및 -Onone 빌드 (Xcode의 디버그 구성에 대한 기본값) : conditionfalse로 평가 되면 인쇄 후 디버깅 가능한 상태에서 프로그램 실행을 중지합니다 message.

  • -O 빌드 (Xcode의 릴리스 구성에 대한 기본값)에서 condition평가되지 않으며 효과가 없습니다.

  • -Ounchecked 빌드에서 condition평가되지 않지만, 최적화가 있다고 가정 할 수 있습니다 으로 평가 true. -Ounchecked 빌드에서 이러한 가정을 충족하지 못하는 것은 심각한 프로그래밍 오류입니다.


2
"하지만 한계를 벗어난 결과 유효 할 수 있고 중요하지 않을 있으므로이를 함께 제공하고 싶지 않을 것입니다. 따라서 앱이 중단되지 않도록해야합니다."이는 저에게 매우 모호합니다. 정확한 예를 포함 해 주시겠습니까? 아마도 일부 코드 일 것입니다.
Honey

2
귀하의 질문에 대한 응답으로 저는 개인적으로 어설 션을 사용하여 작성하고 테스트하는 동안 빌드에서 발생해서는 안되는 일을 포착합니다. data["name"]존재하지 않는 JSON을 읽는 가드 문을 상상해보십시오 . guard..else {} 내부에 어설 션이 있으면 충돌을 일으키고 문제를 해결함으로써 오류를 포착하는 데 도움이됩니다. 유사하게,이 코드가 프로덕션에 있었다면 어설 션은 프로그램을 중단시키지 않으며 내가 사용한 백업 코드 ( return nil)가 인계받습니다.
Alec O

1
색인을 확인하고 전체 앱을 중단하는 대신 아무것도하지 않아야하지 않습니까?
Iulian Onofrei

예, 색인을 확인해야하지만 모든 사람이 가끔 실수를하며 어설 션을 사용하면 잊어 버린 경우 색인을 확인해야한다는 것을 깨닫는 데 도움이됩니다.
Victor Engel

"하지만 범위를 벗어난 결과가 유효 할 수 있고 중요하지 않을 수 있으므로 앱을 중단해서는 안되므로 함께 제공하고 싶지 않을 것입니다." 원하는만큼 많은 어설 션과 함께 앱을 제공 할 수 있습니다. Swift는 릴리스 앱의 assertion 블록 내부에서 조건을 평가하지 않습니다
Akshansh Thakur

90

나는 스위프트 주장을 발견했다 - 도움이 될 누락 된 매뉴얼

                        debug   release   release
function                -Onone  -O       -Ounchecked
assert()                YES     NO        NO
assertionFailure()      YES     NO        NO**
precondition()          YES     YES       NO
preconditionFailure()   YES     YES       YES**
fatalError()*           YES     YES       YES

그리고 Swift Evolution에 대한 흥미로운 토론에서

– assert : 내부 오류에 대한 자체 코드 확인

– 전제 조건 : 고객이 유효한 인수를 제공했는지 확인합니다.

또한 무엇을 사용할지주의해야합니다. assertionFailure 및 최적화 수준을 참조하세요.


자체 코드와 클라이언트의 차이점에 대해 자세히 설명해 주시겠습니까? 클라이언트의 경우 문자열이 예상되는 곳에 숫자를 삽입하는 것과 같은 의미입니까? 간단한 오류 처리로 처리해야하지 않습니까?
Honey

@Honey 나는 그가 네트워크 API 호출 또는 클라이언트 자체 플러그인의 인수 / 결과에 대해 의미한다고 생각합니다.
Chen Li Yong

클라이언트는 라이브러리를 작성하고 프로그래머가 잘못된 데이터를 전달하는 경우 코드를 사용하는 사람입니다. 심각한 프로그래밍 오류로 간주 될 수 있으므로 정상적으로 계속하기를 원하지 않을 것입니다. 사용자에게별로 도움이되지 않는 잘못된 네트워킹 API 데이터로 인해 충돌이 발생해서는 안됩니다.
bompf

@ onmyway133 : Xcode의 빠른 도움말에서, 나는 생각 precondition()하고 preconditionFailure()있다 같은 행동을 가지고 . 이 함수의 차이점은 precondition내부에 조건이 필요하고 preconditionFailure그냥 버려야 한다는 것입니다.
nahung89

12

precondition앱을 출시 할 때 너무 릴리스 모드에서 활성화되고 전제 조건 앱이 종료됩니다 실패했습니다. Assert기본적으로 디버그 모드에서만 작동합니다.

NSHipster에서 사용할 때이 훌륭한 설명을 찾았습니다.

주장은 고전적인 논리에서 차용 한 개념입니다. 논리에서 주장은 증명 내의 명제에 대한 진술입니다. 프로그래밍에서 어설 션은 프로그래머가 선언 된 위치에서 응용 프로그램에 대해 만든 가정을 나타냅니다.

메서드 또는 함수 실행의 시작과 끝에서 코드 상태에 대한 기대치를 설명하는 전제 조건 및 사후 조건의 용량으로 사용되는 경우 어설 션은 계약을 형성합니다. 특정 전제 조건이 실패 할 때 실행을 방지하기 위해 어설 션을 사용하여 런타임에 조건을 적용 할 수도 있습니다.


어설 션은 컴파일러 플래그를 사용하여 활성화 및 비활성화 할 수 있습니다. 배송 된 코드에서 활성화 될 수 있습니다.
Pétur Ingi Egilsson 2015

6

전제 조건

func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

앞으로 진행하기 위해 필요한 조건을 확인하십시오.

  1. 이 기능을 사용하여 배송 코드에서도 프로그램이 진행되지 않도록해야하는 조건을 감지합니다.
  2. 플레이 그라운드 및 -Onone 빌드 (Xcode의 디버그 구성에 대한 기본값) : 조건이 거짓으로 평가되면 메시지를 인쇄 한 후 디버그 가능한 상태에서 프로그램 실행을 중지합니다.
  3. -O 빌드에서 (Xcode의 릴리스 구성에 대한 기본값) : 조건이 거짓으로 평가되면 프로그램 실행을 중지합니다.
  4. -Ounchecked 빌드에서 조건은 평가되지 않지만 옵티마이 저는 그것이 참으로 평가 될 것이라고 가정 할 수 있습니다. -Ounchecked 빌드에서 이러한 가정을 충족하지 못하는 것은 심각한 프로그래밍 오류입니다.

주장하다

func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)

선택적 메시지가있는 전통적인 C 스타일 어설 션입니다.

  1. 테스트 중에 활성화되지만 배송 코드의 성능에 영향을주지 않는 내부 온 전성 검사에이 기능을 사용합니다. 릴리스 빌드에서 잘못된 사용을 확인하려면 전제 조건을 참조하십시오.

  2. 플레이 그라운드 및 -Onone 빌드 (Xcode의 디버그 구성에 대한 기본값) : 조건이 거짓으로 평가되면 메시지를 인쇄 한 후 디버그 가능한 상태에서 프로그램 실행을 중지합니다.

  3. -O 빌드 (Xcode의 릴리스 구성에 대한 기본값)에서 조건이 평가되지 않고 효과가 없습니다.
  4. -Ounchecked 빌드에서 조건은 평가되지 않지만 옵티마이 저는 그것이 참으로 평가 될 것이라고 가정 할 수 있습니다. -Ounchecked 빌드에서 이러한 가정을 충족하지 못하는 것은 심각한 프로그래밍 오류입니다.

0

2 센트를 더하고 싶었습니다. 원하는만큼 코드에 어설 션을 추가 할 수 있습니다. 이러한 어설 션으로 코드를 전송할 수 있습니다. Swift는 프로덕션 앱에 대해 이러한 코드 블록을 평가하지 않습니다. 디버그 모드의 경우에만 평가됩니다.

문서 링크 추가

또한 swift.org에서 이미지 첨부

여기에 이미지 설명 입력

또한 이것은 전제 조건이있는 경우가 아닙니다. 전제 조건과 함께 제공된 코드는 충돌하고 전제 조건이 참으로 평가되지 않으면 앱이 종료됩니다.

즉, 어설 션은 디버깅을위한 것이지만 프로덕션에 영향을주지 않고 제공 될 수 있습니다. 어설 션은 디버그 모드에서 평가되지만 프로덕션에서는 평가되지 않습니다.

사전 조건은 프로덕션 환경에서 예기치 않은 일이 발생하지 않도록하기위한 것입니다. 이러한 조건은 평가되며 거짓으로 평가되는 경우 앱을 종료합니다.

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