Published 2020. 11. 29. 20:08
728x90
반응형

Assertion

assert(_:_file:line:) 함수를 사용한다.
assert 함수는 디버깅 모드에서만 동작한다.
배포하는 애플리케이션에서는 제외된다.
예상했던 조건의 검증을 위하여 사용한다.

다음과 같이 사용해볼 수 있다.

var someInt: Int = 0

assert(someInt == 0, "someInt != 0")

// 확인을 위해 someInt 의 값을 1로 변경
someInt = 1
assert(someInt == 0, "someInt != 0")

========== 출력 결과 ==========
Assertion failed: someInt != 0: file __lldb_expr_33/study23.playground, line 8

 

검증에 실패했고 실패한 메시지가 나타나고 file과 몇 번째 줄인지 순서대로 출력된 것을 확인할 수 있었다.
그리고 assertionFailure() 함수를 사용해서 assert() 의 조건이 실패한 것처럼 동작시킬 수 있다.

if someInt == 1 {
    assertionFailure("assertionFailure")
}

========== 출력 결과 ==========
Fatal error: assertionFailure: file __lldb_expr_37/study23.playground, line 12

 

assert() 함수를 간단하게 사용해보았다.

func functionWithAssert(age: Int?) {
    assert(age != nil, "age == nil")
    
    assert((age! >= 0) && (age! <= 130), "나이값 입력이 잘못되었습니다.")
    
    print("당신의 나이는 \(age!)세 입니다.")
}

functionWithAssert(age: 28)

========== 출력 결과 ==========
당신의 나이는 28세 입니다.

이런 식으로 디버깅할 수 있다.

추가적으로,
테스트를 작성할 때 필수일 뿐만 아니라 코드를 더 쉽게 디버깅이 가능하고 예측가능한 코드를 작성하기 위해 사용한다.
그래서 Assertion 은 코드가 실행될 때 반드시 만족해야 하는 조건을 코드 상에 명시해 놓는 것 이라고 한다.
Assertion 을 사용했을 때 조건에 만족하지 않는다면 문제가 발생할 것이고 어디에서 문제가 발생한 것인지
알 수 있기 때문에 디버깅이 더 쉬워질 수 있다는 것이다.

Assert() 와 비슷한 용도로 사용하는 함수인 precondition() 도 있다.
precondition 의 경우 디버깅 환경뿐만 아니라 릴리즈 환경에서도 사용한다는 차이가 있다.
따라서 배포하는 애플리케이션에서 assert() 함수를 대신해서 사용할 수 있다.

다시 정리해보자면
assert(), assertionFailure()  함수는 디버깅 모드에서만 동작한다.
precondition(), preconditionFailure() 함수는 디버깅 모드와 릴리즈 모드에서 동작한다.

guard (빠른 종료 - Early Exit)

guard를 사용하여 잘못된 값의 전달 시 특정 실행 구문을 빠르게 종료
디버깅 모드 뿐만 아니라 어떤 조건에서도 동작한다.
guard의 else 블럭 내부에는 특정 코드 블럭을 종료하는 지시어(return, break 등)가 꼭 있어야 한다.
타입 캐스팅, 옵셔널과 자주 사용된다.
단순 조건 판단 후 빠르게 종료할 때 용이하다.

다음과 같이 사용해보았다.

func funcGuard(age: Int?) {
    guard let unwrappedAge = age,
          unwrappedAge < 130,
          unwrappedAge >= 0 else {
        print("나이값 입력이 잘못되었습니다.")
        return
    }
    
    print("당신의 나이는 \(unwrappedAge)세 입니다.")
}

funcGuard(age: 28)
funcGuard(age: 140)

========== 출력 결과 ==========
당신의 나이는 28세 입니다.
나이값 입력이 잘못되었습니다.

그리고 단순 조건일 경우 다음과 같이 사용해볼 수 있었다.

var count = 1

while true {
    guard count < 3 else {
        break
    }
    
    print(count)
    count+=1
}

========== 출력 결과 ==========
1
2

 

if let 과 guard let 는 어떻게 다른가?

우선, if let 구문부터 확인해보자.

// if let 구문
func iflet() {
    var someValue: Int?
    someValue = 3
    
    if let unwrapped: Int = someValue {
        print(unwrapped)
    }
    
    // if let 구문 밖에서 사용할 수 없다.
    print(unwrapped)
}

iflet()

=========== 에러 메시지 ==========
error: study23.playground:82:11: error: cannot find 'unwrapped' in scope
    print(unwrapped)
          ^~~~~~~~~

if let 구문에서 unwrapped 라는 상수를 선언해주고 값을 지정해주었다.
밖에서 unwrapped 를 사용하려고 하니 아래와 같은 에러 메시지가 나왔다.
따라서 옵셔널 바인딩 된 상수는 if let 구문 안에서만 사용할 수 있다는 것이다.

그럼 다음으로 guard let 구문을 확인해보자.

// guard let 구문
func guardlet() {
    var someValue: Int?
    someValue = 3
    
    guard let unwrapped: Int = someValue else {
        return
    }

    print("gurad let \(unwrapped)")
}

guardlet()

=========== 출력 결과 ==========
guard let 3

if let 구문과 다르게 guard let 구문 안에서 지정해준 상수를 함수 내부에서 사용할 수 있는 것을 볼 수 있다.
즉, guard let 구문에서 옵셔널 바인딩 된 상수를 함수 내부의 지역 상수처럼 사용할 수 있다는 것이다.
그리고 if let 구문은 따로 else 를 사용하지 않아도 되지만 guard let 구문은 else 구문이 따라와야한다.
그리고 코드 블록 종료 시 코드 블록을 종료하는 지시어가 반드시 있어야 한다. (return, break, continue 등)

각 구문에 대해서 확인해보았는데
guard 를 사용하면 if 보다 훨씬 더 간결하게 사용할 수 있었다.
복잡한 조건이 아닌 예외 사항에 대한 처리를 하고 싶다면 guard 를 사용하는 것이 훨씬 좋을 것이다.

 

assert 와 guard 에 대해서 공부해봤는데
예전에 무작정 앱을 만드려고 따라하면서 보았던 부분들을 간단하게 다루어 보았다.
자세하게 이해는 했다고 할 수 없지만 그래도 어떤 것이구나 하는 정도는 알게 된 것 같다.
guard let 의 경우 여러 예제를 따라해보면서 많이 써본 것 같다.
그런데 assert 는 사실 한 번도 제대로 사용해본 적이 없는 것 같다.
공부하면서 느낀 건 assert 함수를 잘 사용하면 보다 쉽게 코드 관리를 할 수 있겠다는 생각이 들었고
테스트 코드가 중요하다는 글도 많이 보았고 나중에 테스트 코드를 작성하면서 사용해봐야겠다.

 

- 참고 사이트 - 

www.edwith.org/boostcamp_ios/lecture/11313

 

[LECTURE] 25. assert / guard (💎생각해보기) : edwith

생각해보기 assert를 사용해 본 경험이 있나요? 언제 어떻게 사용해봤나요? 사용해본 적이 없다면 언제 어떻게 사용하면 좋을지 이야기해 봅시다. if 구문과 guard 구문은 어... - 부스트코스

www.edwith.org

pilgwon.github.io/blog/2017/09/25/Under-the-Hood-of-Assertions-in-Swift.html

 

Swift의 Assertion 살펴보기

Under the hood of Assertions in Swift

pilgwon.github.io

seorenn.blogspot.com/2016/05/swift-assertion.html

 

Swift - Assertion과 컴파일 최적화

iOS 및 macOS 용 앱 개발, Emacs, Vim, Python 위주로 다루는 Seorenn 개인 블로그

seorenn.blogspot.com

velog.io/@dev-lena/guard-let과-if-let의-차이점

 

guard let과 if let의 차이점

guard let과 if let의 차이점

velog.io

 

728x90
반응형
복사했습니다!