[Swift] 옵셔널

선주·2022년 3월 31일
0

Swift

목록 보기
1/20
post-thumbnail

📌 옵셔널

값이 있을 수도 있고, 없을 수도 있는 변수

let variableOne: Int = nil // 불가능
let variableTwo: Int! = nil // 가능
let variableThree: Int? = nil // 가능

func someFunction(someOptionalParam: Int?) {  }
func someFunction(someParam: Int) {  }

someFunction(someOptionalParam: nil) // 가능
someFunction(someParam: nil) // 불가능

옵셔널의 역할

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

옵셔널의 정의

옵셔널은 enum과 general의 합작품! 옵셔널에 값이 있으면 some의 연관 값인 Wrapped에 값이 할당된다. 즉, 옵셔널이라는 방패막에 보호되어 있는 형태다.

enum Optional<Wrapped> : ExpressibleByNilLiteral {
	case none // 옵셔널에 값이 없을 때
    case some(Wrapped) // 옵셔널에 값이 있을 때
}

옵셔널의 선언

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

전자처럼 선언하는 것이 정석이지만 후자처럼 간단히 선언해줄 수 있다. 물음표는 타입과 반드시 붙여서 작성해야 한다.

옵셔널의 표현

옵셔널은 물음표(?)와 느낌표(!)로 표현할 수 있다.

var optionalValue: Int! = 100
var optionalValue: Int? = 100

옵셔널 타입 자체는 열거형이기 때문에 이런 식으로 switch문을 통해 값이 있고 없음을 확인할 수 있다.

switch optionalValue {
	case .none: // 옵셔널에 값이 없으면
		print(This Optional variable is nil)
	case .some(let value): // 옵셔널에 값이 있으면
		print(Value is \(value))
}

물음표(?) - 일반 옵셔널

옵셔널 타입은 Int 등 일반 타입과는 다른 타입으로 취급되므로, 옵셔널 타입-일반 타입 간의 연산이나 값 교환이 불가능

var optionalValue: Int? = 100

optionalValue = optionalValue + 1 // 기존 변수처럼 사용 불가
optionalValue = nil // nil 할당 가능

느낌표(!) - 암시적 추출 옵셔널

var optionalValue: Int! = 100

optionalValue = optionalValue + 1 // 기존 변수처럼 사용 가능
optionalValue = nil // nil 할당 가능
optionalValue = optionalValue + 1 // 옵셔널에 nil이 할당되어 있을 때 접근 시도 -> 런타임 오류

📌 옵셔널 값 추출

Optional Binding

nil 체크를 함과 동시에 안전하게 값을 꺼내오는 방식
if-let 구문으로 달성!

var myName: String? = nil

if let name: String = myName { // name은 if-let 구문 안에서만 사용 가능
	print(name)
} else {
	print(“myName == nil)
}

한 번에 하나씩만 바인딩할 수 있는가? -> No
쉼표를 사용해 여러 옵셔널 변수들을 한꺼번에 바인딩할 수 있다. if-let 구문에 할당된 모든 옵셔널 변수들에 값이 있어야 해당 구문이 실행된다.

var myName: String? = "yagom"
var yourName: String? = nil

if let name = myName, let friend = yourName {
    print("실행 X \(name) and \(friend)")
} // yourName이 nil이므로 실행 X 두 변수에 모두 값이 들어있어야 실행

yourName = "hana"

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

Force Unwrapping

옵셔널의 값을 강제로 추출하는 방식
보다 안전하게 옵셔널을 사용하기 위해서는 강제 추출보다는 옵셔널 바인딩 사용하기!

func printName(name: String) {
    print(name)
}

var myName: String? = "yagom"
printName(name: myName!) // 강제추출

myName = nil
print(myName!) // 강제추출..했으나 값이 없으므로 런타임 오류

🌟 Quiz

일반 타입 변수에는 nil을 할당할 수 없다.

optionalA는 일반 옵셔널 변수이므로 일반 타입 변수와의 연산이 불가능하다. optionalB는 암시적 추출 옵셔널 변수이므로 일반 타입 변수와의 연산이 가능하지만, optionalB에 현재 nil값이 할당되어 있으므로 에러가 발생한다.

if-let 구문 사용



야곰의 스위프트 기본 문법 강좌를 수강하며 작성한 내용입니다.

profile
기록하는 개발자 👀

0개의 댓글