TIL/Swift 내용 정리

Swift Deep Dive: What is an 'Optional'?

여의도사노비 2023. 2. 20. 18:51
728x90

Optional이 뭘까?

🤖 In Swift, Optional is a type that represents a value that can either have a value or be nil. It is used to handle situations where a value might not be present, or when the absence of a value is meaningful.

Swift에서 Optional은 값을 갖거나 nil일 수 있는 값을 나타내는 타입입니다. 값이 없거나, 값이 없는 것 자체가 의미 있는 상황을 처리하는 데 사용됩니다.

 

For example, let's say you have a function that returns an integer, but in some cases, it might not have a valid integer value to return. In such cases, you can use an optional integer, Int?, to represent the value:

예를 들어 정수를 반환하는 함수가 있지만 경우에 따라 반환할 유효한 정수 값이 없을 수 있습니다. 이러한 경우 Optional 값인 'Int?'를 사용하여 값을 나타낼 수 있습니다.

 

🙋🏻‍♂️ Optional은 Swift를 사용하다보면 정말 많이 쓰게되는 타입이다. 위의 설명에도 나와있듯이 선언된 변수 혹은 상수에 값이 있을 수도 없을 수도 있는 상황에서 활용한다. 직관적으로 생각했을땐 굳이 왜 존재 가능성에 대해서 표시를 해야하는지 이해가 가지 않지만, 막상 개발을 진행하다보면 실제 원하는 타입의 값이 들어오지 않는 경우가 발생할 수 있고. 이는 곧 앱의 Crash(꺼지는 현상 등)를 일으킬 수 있기 때문에 프로그램의 안전을 확보하기 위한 수단이라고 볼 수 있다.

var optionalInt: Int? = 10 // optionalInt is initialized with a value of 10
optionalInt = nil // optionalInt is now set to nil

if optionalInt != nil {
    print("optionalInt has a value of \(optionalInt!)")
} else {
    print("optionalInt is nil")
}

 

Swift를 처음 마주쳤을 때 느낌표와 물음표가 코드를 읽을 때 상당히 난해하게 다가왔던 기억이 있다. 일단 단순하게 생각해서 '?' 물음표는 특정 타입에 Optional 표기를 해준다고 생각하면 된다. 즉 위의 코드에서 optionalInt의 타입은 Int Optional 타입인 것이다. Int Optional이기에 10이 할당될 수도, nil이 할당될 수도 있다. 위에서는 마지막으로 nil이 할당되었고 if 문을 실행하면 else 구문의 "optionalInt is nil"이 실행된다.

 

Optional의 활용에 관하여

🤖 In Swift, you can handle optional values using optional binding or optional chaining.

Swift에서는 optional binding 또는 optional chaining을 사용하여 optional 값을 처리할 수 있습니다.

 

🙋🏻‍♂️ 옵셔널 체이닝과 옵셔널 바인딩은 대표적으로 Optional을 활용할 때 사용하는 방법이다. Optional 자체가 nil을 가질 수도 있기 때문에 nil 값을 받지 않기 위해서 원하는 타입의 값이 정상적으로 저장되었을 경우에만 Optional 타입을 풀고 Int, String 등의 타입으로 치환한다. 물론 이 두 방법외에 더 간단한 방법이 존재한다. 바로 '!' 느낌표이다. 원하는 변수 혹은 상수에 느낌표를 활용하면 강제로 Optional 상태가 풀린다. 이때 Optional 변수에 값이 들어있을 수도 nil이 들어있을 수도 있다. 때문에 강제로 느낌표를 사용하여 Optional 상태를 걷어내는 것은 굉장히 위험하다. 즉 더 안전하게 Optional 타입을 다루기 위해 있는 것이 Optional Chaining, Optional Binding이다.

 

🤖 Optional binding allows you to safely unwrap an optional value and assign it to a non-optional variable or constant, only if the optional contains a non-nil value.

옵셔널 바인딩을 사용하면 옵셔널에 nil이 아닌 값이 포함된 경우에만 옵셔널 값을 안전하게 풀고 옵셔널이 아닌 변수나 상수에 할당할 수 있습니다.

 

let optionalInt: Int? = 10

if let unwrappedInt = optionalInt {
    print("optionalInt has a value of \(unwrappedInt)")
} else {
    print("optionalInt is nil")
}

 

🙋🏻‍♂️ 위 코드에서는 optionalInt의 값이 있는지 없는지 확인을 한 후 unwrappedInt라는 상수에 값을 할당한다. 상수는 변함이 없는 값이기 때문에 만약 optionalInt가 nil이라면 값이 저장되지 않는다. 이때 사용되는 if 구문이 바로 바인딩인데, 만약 optionalInt에 값이 없다면 else 구문이 실행될 것이고 안전하게 에러에 대한 처리 방향을 만들어놓을 수 있다.

 

🤖 Another way to handle optional values is to use optional chaining, which allows you to call a method or access a property on an optional value only if the optional contains a non-nil value.

옵셔널 값을 처리하는 또 다른 방법은 옵셔널 체이닝을 사용하는 것입니다. 옵셔널에 nil이 아닌 값이 포함된 경우에만 옵셔널 값의 속성에 액세스하거나 메서드를 호출할 수 있습니다.

 

let myString: String? = "hello"

if let uppercaseString = myString?.uppercased() {
    print("The uppercase string is \(uppercaseString)")
} else {
    print("myString is nil")
}

 

🙋🏻‍♂️ 위의 바인딩과 비슷한 개념이다. 위의 코드가 할당에 초점을 맞추었다면 아래 코드는 접근에 초점을 맞추었다. String이라는 Struct에는 uppercased 메서드가 정의되어 있는데, 만약 myString이 nil이라면 uppercased 메서드가 String Struct에 접근하지 못할 것이라는 뜻이다. 즉 myString이 nil이 아닌 값이어야 myString에 uppercased() 메서드가 접근하여 값을 불러온 뒤 상수 uppercaseString에 값을 저장할 것이다.

 

이 외에도 nil coalescing 등의 옵셔널 해제 방법이 존재한다!

  

Optional 간단한 정리!

🙋🏻‍♂️ Optional은

  • Swift에서 Optional은 실제로 두 가지 경우가 있는 enum 타입입니다. some과 nil.
    some 케이스는 안에 래핑된 값을 나타내고 nil케이스는 Optional 값이 없음을 나타냅니다.
  • 모든 타입과 함께 사용할 수 있음: 사용자 지정 타입을 포함하여 Swift의 모든 타입과 함께 사용할 수 있습니다.
    예를 들어 다음과 같은 선택적 타입을 가질 수 있습니다.(ex. var optional Person: Person?)
  • 옵셔널 바인딩이나 옵셔널 체이닝을 사용하여 옵셔널 값을 안전하게 언래핑하고 기본 값에 접근할 수 있습니다.
  • nil-coalescing 연산자(??)를 사용하여 Unwrapping 할 수 있습니다. (ex. let result = optionalValue ?? defaultValue)