iOS/Swift

옵셔널

밤새는 탐험가89 2024. 1. 16. 11:42

 

Optional | Apple Developer Documentation

 

Optional | Apple Developer Documentation

A type that represents either a wrapped value or the absence of a value.

developer.apple.com

 

옵셔널

이 '있을 수도' 또는 '없을 수도'를 나타내는 표현

즉, 변수 또는 상수에 값이 nil 일 수도 있다는 표현

 

 

 

옵셔널 사용 

값의 유무를 뜻하는 게 바로 옵셔널 사용 목적

count 라는 변수에 0을 할당한다면? 이는 0이라는 값을 저장한다는 의미

myFruit 라는 변수에 " " (빈 값)을 할당한다면? '빈 문자열'을 저장한다는 의미 

 

★ 변수 또는 상수에 정말 값이 없다면 = 'nil' 할당 ★

 

 

오류가 발생하는 nil 할당 

var myFruit: String = "apple"
myFruit = nil    // 오류 발생

 

myFruit이라는 변수에 nil을 할당하면 오류 발생 

★ 'nil'은 옵셔널로 선언된 곳에서만 사용 가능 ★

 

 

옵셔널 변수의 선언 및 nil 할당 

var myFruit: String? = "apple"
print(myFruit)
// Optional("apple"



myFruit = nil
print(myFruit)
// nil

 

 

★ 옵셔널 사용 목적

옵셔널을 통해 기능상의 오류를 'nil'로써 반환하여 

오류의 유무를 간단하게 파악 가능 

 

매개변수의 타입을 옵셔널로 정의하여 간단하게 

해당 매개변수에 대해 값의 유무 파악 가능 

 

 

 

switch를 통한 옵셔널의 값 확인

func checkFruit(check name: String?) {
    
    switch name {
        case .none:
        print("이건 nil이에요")
        case .some(let check):
        print("이 과일 이름은 \(check)이에요")
    }
}


var myFruit: String? = "apple"
checkFruit(check: myFruit)

// 이 과일 이름은 apple이에요

myFruit = nil
checkFruit(check: myFruit)
// 이건 nil이에요

 

옵셔널은 열거형으로 구현

옵셔널 자체가 열거형이기 때문에 

swith 구문을 통해 옵셔널 변수의 값 유무를 파악가능 

 

 

 

옵셔널 추출

옵셔널로 선언된 변수 또는 상수의 값을 출력하면 

Optioonal("apple") 라고 나옴

var myFruit: String? = "apple"
print(myFruit)
// Optional("apple")

 

 

 

만약에 myFruit을 설명하는 변수 myFruitInfo에 myFruit 값을 호출한다면?

Optioonal("apple") 이 붙은 상태로 출력됨

var myFruit: String? = "apple"

var myFruitInfo: String = "\(myFruit)은 제가 좋아하는 과일 입니다."
print(myFruitInfo)
// Optional("apple")은 제가 좋아하는 과일 입니다.

 

 

 

옵셔널로 선언된 myNum과 옵셔널로 선언되지 않은 yourNum을 더한다면?

오류 발생 

var myNum: Int? = 3

var yourNum: Int = 4

print(myNum + yourNum)  // 오류 발생

 

 

따라서 옵셔널의 값을 옵셔널이 아닌 값으로 추출하는 방법이 필요 

 

 

 

강제 추출

가장 간단하지만, 위험한 방법으로 런타임 오류 발생 가능 높음 

 

추출 방법은 추출하고자하는 값 뒤에 느낌표 (!)를 붙임 

값이 nil 이라면 런타임 오류 발생 

 

 

옵셔널 값의 강제 추출 

var myNum: Int? = 3

var yourNum: Int = 4

print(myNum! + yourNum)   // 7

myNum = nil
print(myNum! + yourNum)   // 오류발생

 

★ 런타임 오류의 가능성을 항상 내포하고 있기 때문에 

옵셔널 강제 추출 방식은 비추천 ★ 

 

 

 

옵셔널 바인딩

 

if 구문을 통해 안전하게 옵셔널 값을 추출하는 방식

var myFruit: String? = "apple"
print(myFruit)
// Optional("apple")



// 옵셔널 바인딩을 통한 임시 상수 할당 
if let fruit = myFruit {
    print("my fruit is \(fruit)")
} else {
    print("fruit == nil")
}
// my fruit is apple




// 옵셔널 바인딩을 통한 임시 변수 할당 
if var fruit = myFruit {
    fruit = "Banana"    // 변수이므로 내부에서 변경 가능
    print("My fruit is \(fruit)")
} else {
    print("fruit == nil")
}
// My fruit is Banana

 

 

 

첫 번째 if 구문에서 fruit 라는 임시 변수 또는 상수는 해당 블록 내부에서 사용 가능

(따라서 두 if 구문에 서로 fruit 이라는 이름을 사용해도 충돌 없음)

 

 

만약에 옵셔널 바인등을 통해 한 번에 여러 옵셔널의 값을 추출하려고 한다면?

쉼표 (,)를 통해 구분하여 옵셔널을 나열할 것 

(단, 바인딩하려는 옵셔널 중 하나라도 값이 없다면 -> 내부 명령문은 실행되지 않음)

 

 

 

암시적 추출 옵셔널 

로직상 nil 때문에 런타임 오류가 발생하지 않는다고 생각될 떄,

옵셔널 바인딩으로 값을 추출하기 어려울 때 등에 사용하는 것이 암시적 추출 옵셔널

 

옵셔널을 표시하고자하는 타입 뒤에 느낌표(!)를 붙임 

 

일반 값처럼 사용 또는 nil 할당 가능 

 

nil이 할당된 상태에서 접근한다면? 런타임 오류 발생 

 

압시적 추출 옵셔널의 사용

var myNum: Int! = 10
print(myNum)    // 10

var yourNum: Int = 10
print(myNum + yourNum)    // 20



var myFruit: String! = "apple"
print(myFruit)    // apple

myFruit = nil

// 암시적 추출 옵셔널도 바인딩 사용 가능 
if let fruit = myFruit {
    print("my fruit is \(fruit)")
} else {
    print("fruit == nil")
}
// fruit == nil

'iOS > Swift' 카테고리의 다른 글

클래스  (0) 2024.01.17
구조체  (0) 2024.01.17
함수 3편 (중첩 함수)  (1) 2024.01.15
함수 2편 (매개변수, 데이터 타입)  (0) 2024.01.14
함수 1편 (함수 정의 및 호출)  (0) 2024.01.14