[Swift] Optional


Swift Optional Type


옵셔널

  • 스위프트의 특징 중 하나인 안정성을 문법으로 담보하는 기능
  • 타입을 선언하고 값이 없으면 에러가 나는데 옵셔널 타입은 값을 넣지 않아도 nil이라는 임시 값이 들어가기 때문에 자주 활용

옵셔널 타입

let num1: Int? = 2  // 간편 표기
let num2: Optional<Int> = 2  // 정식  문법

옵셔널은 nil이거나 nil이 아닌 값만 가질 수 있다.

  • nil : 값이 할당되지 않아 오류가 발생했을 때
  • nil 아닌 값 : 오류가 발생하지 않았을 때 반환하려는 값이 옵셔널로 래핑된 형태의 값

Int (정수형 타입) / Int? (옵셔널 정수형 타입) / Double (실수형) / Double? (옵셔널 실수형 타입)

-> 각각 서로 다른 타입이다.

nil은 실제로 값이 없는 것은 아니고 값이 없음을 표현하는 키워드
실제로 값이 없는 다른 언어의 null과는 실제로 값이 없는 것이 아니라서 다른 것

var num1: Int = nil  // 에러
var num2: Int? = nil  
// nil을 넣는다고 해도 옵셔널 타입은 타입 추론으로 자동으로 할당되지않아서 지정 해 줘야 한다.
var optionalNum : Int?

print(optionalNum) // nil

-> 옵셔널 타입끼리는 계산이 불가능하기 때문에 값을 추출해 주어야 한다.

옵셔널 값을 추출하는 방법

1. 강제로 값을 추출

var optionalNum: Int? = nil
optionalNum = 10

print(optionalNum)  // Optional(10)
print(optionalNum!)  // 10
//느낌표를 붙여주면 강제로 옵셔널을 벗김
  • 값이 있다는 것이 확실할 때 사용
  • nil로 초기화가 되어있을 때 강제로 추출하면 에러가 남

2. if문으로 nil이 아니라는 것을 확인 한 후, 강제로 벗기기

if str != nil {
    print(str!)
}

3 옵셔널 바인딩 (if let 바인딩)

  • 바인딩이 된다면, 특정 작업을 하겠다는 의미
  • 가장 많이 사용되는 방법
if let s = str {
	print(s)
}
func doSomething(name: String?) {
    guard let n = name else { return }
    print(n)
}

doSomething(name: "hello")

실제로 앱을 만들때는 guard let 바인딩 패턴을 많이 사용

4 닐 코얼레싱 연산자를 사용하는 방법

  • 옵셔널 타입에 대하여, 디폴트 값을 제시할 수 있을 때 사용
  • 직접 값을 벗겨서 사용하는 것이 아니고, 디폴트 값 제시를 통해 옵셔널 가능성을 없애는 방법
var serverName: String? = "홍길동"

var userName = serverName ?? "미인증사용자"    // String타입
//nil인 경우 “미인증사용자”를 출력

optionalName != nil ? optionalName! : "홍길동"
//삼항연산자를 이용한 풀이

옵셔널 체이닝

  • 옵셔널타입에 대해, 접근연산자를 사용할때, ?(물음표)를 붙여서, 앞의 타입이 값이 nil을 가질 수도 있음을 표시
    • 결과는 항상 옵셔널타입으로 리턴
    • 옵셔널 체이닝 과정에서 그 값 중 하나라도 nil을 리턴한다면, 이어지는 표현식을 평가하지 않고 nil 리턴
  • 옵셔널 타입을 함수 파라미터로 사용
func doSomePrint(with label: String, name: String? = nil) {   // String? = nil
    print("\(label): \(name)")
}

doSomePrint(with: "레이블", name: "스티브 잡스")
doSomePrint(with: "레이블", name: nil)
doSomePrint(with: "레이블")
// 모두 에러없이 실행 됨
  • 헷갈릴 수 있는 부분
// 함수
Dog?.sit?()?.name
// Dog?.sit? -> 함수가 없을 수도 있다는 뜻
// Dog?.sit?()? -> 함수의 결과값이 없을 수도 있다는 뜻

// 딕셔너리
books?["Apple"]?.name
// books? -> 딕셔너리가 없을 수도 있다는 뜻
// books?["Apple"]? -> 딕셔너리의 결과값이 없을 수도 있다는 뜻
  • 옵셔널 타입에 접근해서 사용하는 함수는 앞의 타입을 벗기지 않아도 사용 가능
    (함수 자체가 옵셔널 타입은 아니기 때문에 함수를 벗겨서 사용할 필요 없음)
    • 함수가 리턴형이 없는 경우
      • 타입에 값이 있으면 함수 실행
      • 타입에 값이 없으면 nil
    • 함수가 리턴형이 있는 경우
      • 타입에 값이 있으면 옵셔널 리턴 타입으로 반환
        (원래 리턴형 옵셔널이 아니어도)
      • 타입에 값이 없으면 nil로 반환

IUO(Implicitly Unwrapped Optional)

  • 옵셔널 묵시적 추출
  • 굉장히 많이 사용되는 방식
  • 이 개념은 추후에 다시 다루도록 함

참고

Ellen Swift Class






© 2021. by hminkim