Optional

권현석·2022년 12월 12일
0

Optional

  • 값이 있을 수도 없을 수도 있다.
    (= 변수 or 상수에 값이 꼭 있다고 보장X = 변수 or 상수 값이 nil일 수 있다.)
  • 데이터 타입 뒤에 물음표(?) 붙여서 표현
var studentName: String? = "철수"

*빈 문자열과 nil은 같지 않다.

  • nil은 값이 정말로 없는 것을 뜻함)
  • nil은 optional이 선언된 곳에서만 사용가능
  • nil은 argument가 잘 못 되었을 때 nil을 반환해 오류가 있음을 알림

optional은 '열거형'이다.

  • 값을 가질 시: some 케이스
  • 값이 없을 시: none 케이스(값에 Wrapped가 할당됨)
    =>값이 optional이란 열거형의 방패막에 보호되어 래핑 되어있는 모습이다.
  • optional 자체가 열거형이라 optioanl variable은 switch구문으로 값이 있고 없음 확인 가능하나 이를 이용해 매번 값이 있는지 확인하는 건 불편함

Optional Unwrapping(옵셔널 추출)

optional unwrapping: 옵셔널 값을 옵셔널이 아닌 값으로 추출하는 것

Froced Unwrapping(강제추출)

=> 가장 간단하나 가장 위험함(런타임 오류 가능성 가장 높기 때문, 옵셔널 만든 의미 무색해짐), 'xcode! 내가 너보다 코드 잘 파악하고 있으니까 unwrapping해!'이런 느낌으로 사용함

  • 옵셔널 값 뒤에 느낌표(!) 붙이기(옵셔널 없는 경우 런타임 오류)
var myName: String? = "alex"

// 옵셔널이 아닌 값에 옵셔널 못 들어감. 추출해서 할당해주어야 함.
var alex: String = myName!

myName = nil
alex = myName!  // 런타임 오류

//if 구문 등 조건문 이용해 좀 더 안전하게 처리 가능하지만 myName이 나올 때 마다 느낌표(!)를 붙여 unwrapping 해야함.
if myName != nil {
	print("My name is \(myName!)")
}else {
	print("myName == nil")
}
// myName == nil

Optinal Binding(옵셔널 바인딩)

  • 값이 있는 경우 optional에서 추출한 값을 일정 블록 안에서 사용 가능한 상수, 변수로 할당해 optional이 아닌 형태로 사용할 수 있도록 도움
  • if, while 구문 등과 결합해 사용가능
var myName: String? = "alex"

// 옵셔널 바인딩 통한 임시 상수 할당
if let name = myName {
	print("My name is \(name)")
}else {
	print("myName == nil")
}
// My name is alex

// 옵셔널 바인딩 통한 임시 변수 할당
if var name = myName {
	name = "wizpaln"	// 변수이므로 내부에서 변경 가능
    print("My name is \(name)")
}else {
	print("myName == nil")
}
// My name is wizplan
  • if let name = myname에서 optional값인 myName을 optional이 아닌 name에 binding해주어 unwrapping하는 것.
    => myName을 name에 할당해 myName박스를 열어 안에 뭐가 있는지 확인하고, 만약 myName가 nil이면 else 구문 실행, nil이 아니면 myName의 값을 myName 안의 name에 할당해 if 구문 실행.

상수 name은 if 블록 안에서만 사용(else 블록에서도 사용 불가) 하기 때문에 충돌X

  • 쉼표(,) 사용해 바인딩 할 옵셔널 나열해 한번에 여러 옵셔널의 값 추출 가능
var myName: String? = "alex"
var yourName: String? = nil

// friend에 바인딩 안되서 실행 안됨
if let name = myName, let friend = yourName {
	print("We are friend! \(name) & \(friend)")
}

yourName = "hudson"

if let name = myName, let friend = yourName {
	print("We are friend! (name) & \(friend)")
}
// We are friend! alex & hudson

Nil Coalescing Operator

optional ?? defaultValue

?? : 앞의 optional이 nil인지, 아닌지 확인하는 역할
optional이 nil이면 defaultVaue를 사용하고,
nil이 아니면 optional에 할당된 값 사용.

Optional Chaining

optional?.property
optional?.method
  • 위의 다른 방법들은 optional이 간단한 값을 가졌을 때 사용하지만 optional chaining의 경우는 optional이 structure와 같은 구조를 가졌을 때 optional의 property, method에 접근하기 위해 사용한다.

  • optional이 nil인 경우 충돌은 일어나지 않지만 property와 method는 어떠한 값도 가질 수 없다.(즉, nil이다.) 하지만 nil이 아닌 경우 property와 method에 접근가능하다.

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

  • nil 때문에 런타임 오류 발생 안 할거라는 확신이 들거나 optional binding으로 매번 값 추출이 귀찮을 때 nil을 할당해 줄 수 있는 옵셔널이 아닌 변수나 상수가 있으면 좋다
    => 값이 nil이 아니라는 확신이 있으면 느낌표(!)로 unwrap한 변수 or 상수가 있으면 좋다.

  • Implicitly Unwrapped Optional은 타입 뒤에 느낌표(!)를 사용

var myName: String! = "alex"
  • Implicitly Unwrapped Optional로 지정된 타입은 일반 값처럼 사용 가능하나 옵셔널이라 nil도 할당가능.

⭐︎ 옵셔널 사용 시 옵셔널 바인딩, nil 병합 연산자, 옵셔널 체이닝 사용이 훨씬 안전함.

profile
wanna be an iOS developer

0개의 댓글