• 다음은 Swift 5.6 Doc의 The Basics 공부 내용을 정리했음을 밝힙니다.

The Basics

옵셔널

스위프트는 C, Objective-C와 달리 어떤 타입의 값이든 옵셔널을 사용해 "값이 있거나 없는 상황"을 모두 처리할 수 있다.

  • Objectvie-C에서 널 값을 통해 오브젝트 값이 없는 상황을 표현하거나 특정 메소드의 반환 상수를 통해 확인해야 했던 반면, 스위프트는 일괄적으로 옵셔널을 적용할 수 있다.
  • 값을 변환할 때에도 실패할 수 있는 상황까지 포함해 스위프트는 옵셔널을 적용한다.
  • ?을 타입 뒤에 붙여 옵셔널을 표시한다.
var digits:String = "1234567"
var numbers = Int(digits)
// digits -> Int? or optional Int

스위프트는 옵셔널이 아닌 변수와 상수에게 널 값을 허용하지 않는다.

  • 옵셔널 변수로 선언한 뒤 값을 주지 않으면 널 값이 자동으로 설정된다.

옵셔널 변수가 아니라면 널을 사용할 수 없다는 게 가장 큰 차이점이다. 옵셔널 변수를 사용해 타입 세이프티를 확보할 수 있다는 점에서 스위프트는 다른 선택을 내린 것 같다.

If문 과 강제 언래핑

  • 옵셔널이 값을 가지고 있는지 nil과 비교 연산자 == 또는 !=을 통해 확인할 수 있다.
  • 널이 아닌게 확실하다면 !을 옵셔널 다음에 붙여 사용할 수 있다. 즉 "값이 있다고 확인"했다는 선언이며, 이를 강제 언래핑(forced unwrapping)이라고 한다.

값이 없는 옵셔널 값에 접근하면 런타임 에러가 일어난다.

옵셔널 바인딩

!을 사용하는 강제 언래핑은 nil 값을 가지는 위험이 있다. 바인딩을 통해 옵셔널 표현식이 값을 가지는지 crush 위험 없이 판단할 수 있다.

  • 옵셔널 표현식을 변수나 상수에 값을 넘겨줄 때 "값이 있다면" 자연스럽게 언래핑된다. If 문을 통해 언래핑이 "되었음"을 확인할 수 있다.
  • 옵셔널 바인딩은 If 문, While 문에서 활용된다.
let a:Int? = 123

if let b = a {
    print("\(b) is non-nil")
} else {
  print("a is nil")
}
// "123 is non-nil"
  • 여러 옵셔널 표현식을 평가할 때에도 조건문 안에 ,로 값을 언래핑하면 된다.

강제 언래핑보다 옵셔널 바인딩이 더 안전한 방식이다.

암시적으로 언래핑한 옵셔널

옵셔널 표현식을 사용할 때 값이 들어간 게 확실한 이후에는 언래핑할 필요 없이 옵셔널 표현식을 사용할 수 있다. 즉 "옵셔널 값을 설정했으니 여기에는 앞으로 계속해서 값이 들어 있다!"는 말이다.

  • 옵셔널 값을 사용할 때가 아니라 옵셔널에 값을 준 이후에 !로 선언하자.
let str1:String? = "an optional string"
let fored_str:String = str1!

let str2:String! = "an implicitly unwrapped optional string"
let implicit_str:String = str2

암시적으로 언래핑한 옵셔널을 If 문을 사용한 nil과의 비교, 옵셔널 바인딩과 함께 사용할 수 있다.

이후에 nil이 될 수 있는 변수는 암시적으로 언래핑해서 사용하면 안 된다.

에러 핸들링

스위프트는 에러 조건에 맞추어 핸들링할 수 있다. 옵셔널과 달리 failure의 원인을 구체적으로 다룰 수 있고, 또한 에러를 다른 방향으로 throw할 수 있다.

func canThrowAnError() throws {
    // this function may or may not throw an error
}

do {
    try canThrowAnError()
    // no error was thrown
} catch {
    // an error was thrown
}

기본적으로 Java 등 타 프로그래밍 언어의 try catch 문과 같은 양식이다.

Assertions and Preconditions

이후 코드를 실행하기 전에 필수적인 조건을 충족했는지 런타임 도중에 확인할 수 있다. assertion 또는 precondition 문 안에 존재하는 불리언 값이 참이라면 코드를 계속 이어가면 되고, 아니라면 더 이상 현재 상태가 유효하지 않다는 뜻이므로 앱 자체가 종료된다.

  • assertion은 빌드를 디버깅할 때 코딩의 실수 및 정확하지 않은 가정을, precondition은 디버깅이나 production을 할 때 일어나는 이슈를 잡도록 도와준다.
  • 에러 핸들링과 다르게 assertion failure은 프로그램 상태 자체가 유효하지 않음을 런타임 도중에 나타내기 때문에 catch할 수 없다.
  • 유효한 데이터를 통해 앱이 보다 예측 가능한 상태로 종료하도록, 그리고 디버깅하기 쉽도록 만들자.

assertion으로 디버깅하기

assert 함수를 사용해 assertion 문을 작성할 수 있다. 이 함수를 통해 특정 표현식이 참인지 거짓인지 판단할 수 있다. 다음 age 값을 기준으로 assert fail이 발생한다.

let age = 300
assert(age>=0 && age<=120, "check your age range")

precondition 강제하기

조건문이 거짓일 수 있는 상황에서 precondition 함수를 사용하자. 이때 코드가 계속해서 실행되는 게 확실해야 한다. 아래 상황에서 index 값은 양수여야 한다.

// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")

fatalError 함수를 통해 프로토타입 개발 또는 초기 개발 시 stub 함수를 사용할 수 있다.

profile
JUST DO IT

0개의 댓글

Powered by GraphCDN, the GraphQL CDN