이것저것 적어보는 블로그

Swift 옵셔널(Optional) 본문

개발&코딩/Swift

Swift 옵셔널(Optional)

dona0408 2022. 12. 12. 02:24
반응형

Swift를 공부하면서 매번 제대로 정리가 안되는 개념이 있는데 바로 옵셔널(Optional)이다.

그래서 이참에 포스팅하면서 정리해두려고 한다.

 

옵셔널이란 변수의 값이 있을 수도 있고 없을 수도 있다는걸 나타낸다.

불편해보이는 Optional 왜 사용할까 싶은데
Objective-C에 아직 nil타입이 존재하며, 프로젝트에서 obj-c와 swift를 혼용해서 사용할 수 있어 obj-c와 상호운용성을 위해 사용한다고 한다.

 

옵셔널이 필요한 이유 -> nil의 가능성을 명시적으로 표현
Type casting, nil value 체크 등에 있어서 중요한 역할

  • nil 가능성을 문서화 하지 않아도 코드만으로 충분히 표현가능
    • 문서 / 주석 작성 시간을 절약
  • 전달 받은 값이 옵셔널이 아니라면 nil체크를 하지 않더라도 안심하고 사용
    • 효율적인 코딩
    • 예외 상황을 최소화하는 안전한 코딩

옵셔널이 아닌 상수에다가 nil값을 할당 시 컴파일 오류 발생

옵셔널은 열거형과 제너럴의 합작품. 아래와 같이 선언이 되어 있다.

enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
}

let optionalValue: Optional<Int> = nil
let optionalValue: Int? = nil

var optionalValue: Optional<Int> = 100 (완전한 문법)
var optionalValue: Int? = 100 (간략한 표현)

! - Implicitly Unwrapped (암시적 추출 옵셔널)

var optionalValue: Int! = 100

// 기존 변수처럼 사용 가능
optionalValue = optionalValue + 1

// nil 할당 가능
optionalValue = nil

// 잘못된 접근으로 인한 런타임 오류 발생, optionalValue에 nil이 들어가 있기 때문!
optionalValue = optionalValue + 1

? - 일반적인 옵셔널

var optionalValue: Int? = 100

// nil 할당 가능
optionalValue = nil

// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산불가
optionalValue = optionalValue + 1

Optional Unwrapping, 옵셔널을 꺼내는 방법은 2가지 방법이 있다.

 

먼저, Optional Binding(옵셔널 바인딩)
nil체크 + 안전한 값 추출을 하는 방식으로, 옵셔널에 값이 있는 경우에만 값을 추출
if-let/var 방식, guard-let 방식을 이용한다.

// if-let 방식
func printName(_ name: String) {
    print(name)
}

var myName: String? = nil

//printName(myName)
// 전달되는 값의 타입이 다르기 때문에 컴파일 오류발생

if let name: String = myName {
    printName(name)
} else {
    print("myName == nil")
}

// name 상수는 if-let 구문 내에서만 사용가능합니다
// 상수 사용범위를 벗어났기 때문에 컴파일 오류 발생
//printName(name)

힌번에 하나만 바인딩 가능한게 아닌 여러개 동시에도 가능합니다.

myName = "yagom"
yourName = nil

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yourName이 nil이기 때문에 실행되지 않습니다

yourName = "hana"

if let name = myName, let friend = yourName {
    print("\(name) and \(friend)")
}
// yagom and hana

guard-let은 if-let과 비슷하지만, else인 부분만 작성이 가능하다.
값이 nil이여서 옵셔널이 추출되지 않은 경우만 어떠한 액션이 가능!
guard-let을 통과한 경우 저장된 상수는 전역변수로 사용 가능!!
guard-let의 else문 안에는 항상 return 아니면 throw문이 와야 한다.

// guard-let 방식
func optbinding(){
    guard let name_m: String = myName else {
        return print("myName is Optional")
    }
    print(name_m)

    guard let name_y: String = yourName else {
        return print("yourName is Optional")
    }
    print(name_y)
}

optbinding()

Force Unwrapping (옵셔널 강제 추출)
옵셔널 변수명 + !, 그다지 추천되는 방식은 아니다

printName(myName!) // yagom
myName = nil

// print(myName!)
// 강제추출시 값이 없으므로 런타임 오류 발생

var yourName: String! = nil

//printName(yourName)
// nil 값이 전달되기 때문에 런타임 오류발생
반응형

'개발&코딩 > Swift' 카테고리의 다른 글

Swift Strong과 Weak 그리고 Unowned  (0) 2022.10.09
Swift 변수명 규칙  (0) 2022.10.08
Swift 함수 기본 문법  (0) 2020.12.27
Comments