Swift '문법'

옵셔널

김동준. 2024. 6. 27. 23:46

Optional Swift 언어에서 중요한 개념으로, 값이 존재할 수도 있고 존재하지 않을 수도 있음을 표현합니다. 이는 변수나 상수에 값이 없는 경우를 안전하게 처리하는 도움이 됩니다. 옵셔널은 nil 값을 가질 있는 변수나 상수를 나타내며 옵셔널을 사용하는 방법에는 여러 가지가 있습니다.

옵셔널 선언

옵셔널은 '?'를 사용하여 선언합니다. 이는 값이 있을 수도 있고 없을 수도 있음을 나타냅니다.

var optionalString: String? = "Hello, world!"
var optionalInt: Int? = 42
var optionalDouble: Double? = nil

옵셔널의 언래핑 (Unwrapping)

옵셔널 변수를 사용할 떄는 값을 안전하게 추출해야 합니다. 이를 "언래핑"이라고 합니다. 여러가지 언래핑 방법이 있습니다.

1.강제 언래핑(Forced Unwrapping)

강제 언래핑은 '!' 를 사용하여 옵셔널 값을 강제로 추출합니다.하지만 값이 'nil'인 경우 런타임 오류가 발생할 수 있습니다.

let optionalString: String? = "Hello"
if optionalString != nil {
  print(optionalString!) //"Hello"
}

2.옵셔널 바인딩(Optional Binding)

옵셔널 바인딩은 if let 또는 guard let 구문을 사용하여 안전하게 옵셔널 값을 추출합니다.

if let unwrappedString = optionalString {
    print(unwrappedString) // "Hello"
} else {
    print("optionalString is nil")
}

guard let unwrappedString = optionalString else {
    print("optionalString is nil")
    return
}
print(unwrappedString) // "Hello"

3.Nil-Coalescing 연산자

Nil-Coalescing 연산자(??)는 옵셔널이 nil인 경우 기본 값을 제공할 수 있습니다.

let optionalString: String? = nil
let resultString = optionalString ?? "Default Value"
print(resultString) // "Default Value"

4.옵셔널 체이닝(Optional Chaining)

옵셔널 체이닝은 옵셔널 값에 접근할 때 여러 단계에 걸쳐 안전하게 접근할 수 있도록 도와줍니다.

struct Person {
    var name: String
    var address: Address?
}

struct Address {
    var city: String
}

let john = Person(name: "John", address: Address(city: "New York"))
let city = john.address?.city // "New York"

let jane = Person(name: "Jane", address: nil)
let noCity = jane.address?.city // nil

 

5.암시적 언래핑 옵셔널(lmplicitly Unwrapped Optionals)

암시적 언래핑 옵셔널은 !로 선언하며, 사용 시 자동으로 언래핑됩니다. 이는 초기화 이후에 nil이 될 수 없는 변수에 사용합니다.

var implicitlyUnwrappedString: String! = "Hello, world!"
print(implicitlyUnwrappedString) // "Hello, world!"
implicitlyUnwrappedString = nil

옵셔널의 활용

옵셔널은 주로 다음과 같은 상황에서 사용됩니다.

1.함수나 메서드에서 값을 반환하지 않을 수 있을 떄:

함수나 메서드가 특정 상황에서 값을 반환하지 못할 경우 'nil' 을 반환하도록 합니다.

2.외부 입력값이 유효하지 않을 수 있을 떄:

사용자가 입력한 값이나 외부에서 받아온 값이 유효하지 않을 경우 옵셔널로 처리합니다.

3.초기값이 없을 수 있는 변수나 상수를 선언할 떄:

변수나 상수의 초기값이 나중에 설정될 수 있거나, 존재하지 않을 수 있는 경우 옵셔널로 선언합니다.

옵셔널을 사용하는 함수

func findIndex(of value: Int, in array: [Int]) -> Int? {
    for (index, element) in array.enumerated() where element == value {
        return index
    }
    return nil
}

let numbers = [1, 2, 3, 4, 5]
if let index = findIndex(of: 3, in: numbers) {
    print("Index: \(index)") // "Index: 2"
} else {
    print("Value not found")
}

if let index = findIndex(of: 6, in: numbers) {
    print("Index: \(index)")
} else {
    print("Value not found") // "Value not found"
}

findIndex(of:in:) 함수는 배열에서 특정 값의 인덱스를 찾고, 값을 찾으면 그 인덱스를 옵셔널로 반환하며, 값을 찾지 못하면 nil을 반환합니다. 이를 통해 함수 호출자가 값을 안전하게 처리할 수 있습니다.