let name : String?
이렇게 변수를 선언하거나 할 때 타입 뒤 에 붙어있는 ? 물음표가 옵셔널!
-'nil' 이라는 값을 가질 수 있으면 Optional Type이고,
이 Optional Type을 선언할 땐 타입 옆에 ?(물음표)를 붙인다
예시 ) let animal = ["name" : "Fubao", "gender" : "female"] let name = animal["name"] // "Fubao" let name = animal["alias"] // nil
- 입력한 키값이 없다고 컴파일 오류를 낼 수는 없고,
리턴을 안 할 수도 없고, 공백을 리턴 해 줄 수도 없기 때문에 오류가 났다고 알려주는 의미로 이 값을 nil로 출력해 주는 것!
예시) //선언과 동시에 초기화 해준 변수(상수),
Type Annotation을 사용해서 사용해온 변수(상수)var name = "jjoohee" var name : String name = "jjoohee"
var name : String
name = nil //ERROR
Non-Optional Type에서 값이 없을 경우 에러가 남
var name : String?
var name : String?
name = nil
let a: Int? = nil
let b =a
옵셔널 타입의 값인 a를 b에다가 선언과 동시에 초기화 해주면
let b = a //nil
b도 옵셔널 타입으로 선언됨
var alias: String
var name: String?
print(type(of: alias)) // 결과값 : String
print(type(of: name)) // 결과값 : Optional<String>
Optional<String>
의 값을 사용할 땐 옵셔널을 언래핑 해서 사용해야함!!!
let a: Int? = nil
print(type(of: a))
그냥 Int 자료형이 아닌, Optional Int 자료형임.
따라서 Optional 자료형을 사용하기 위해선,
Optional이란 포장지를 까주고 써야 함
만약 Optional이란 포장지를 제거하지 않는다면?
let a: Int? = nil
a = 4
var myInfo = " 내 나이는 \(a)살 입니다"
이런식으로 출력해보면 내 나이는 Optional(4)살 입니다.
Optional Unwrapping을 하기 위해선
절대 Unwrapping 하고자 하는 변수(상수)가 nil이면 안 된다
Optional로 선언된 변수(상수)를 사용할 때 그 뒤에 !를 붙여주면 됨
let a: Int? = nil
a = 4
var myInfo = " 내 나이는 \(a!)살 입니다"
// 출력값 : 내 나이는 4살 입니다
if let name : Type = OptionalExpression {
}
while let name : Type = OptionalExpression {
}
guard let name : Type = OptionalExpression {
}
참고로 while을 이용한 방법은 거의 사용되지 않기 때문에, while은 제외하고 알아볼 거임
let optionalNumber: Int? = 4
if let nonOptionalNumber = optionalNumber {
print(nonOptionalNumber)
} else {
print(optionalNumber)
} // 출력값 : 4
let optionalNumber: Int? = nil // 출력값은 4
옵셔널 바인딩 if let 매커니즘
① 표현식이 nil인지 아닌지 판별하자
② 표현식이 nil이 아닌 경우
nonOptionalNum 이라고 if let을 통해 선언된 상수의 scope는 if 구문임 > if 문 밖에서는 nonOptionalNum이라는 상수에 접근할 수 없음!
nonOptionalNum은 optionalNum을 Unwrapping 한 값을 대입한 것 뿐, optionalNum의 값은 여전히 Optional Type이다!
if let nonOptionalNumber = optionalNumber {
print(nonOptionalNumber)
print(optionalNumber)
}
4
Optional(4)
optionalNum을 Unwrapping 한 값이 nonOptionalNum일 뿐, optionalNum은 여전히 Optional Type의 값
③ 표현식이 nil인 경우
nil인 경우엔 if 구문을 거치지 않고 else 구문으로 빠짐, 당연하게도 nonOptionalNum 이란 상수는 사용할 수 없음
💡. TIP
Non Optional Type의 이름
- 그냥 Optional Type의 이름을 그대로 똑같이 써도 됨
만약 두 개의 변수가 서로 다른 Scope에서 같은 이름으로 선언된 경우, 실행 시점에서 가까운 곳에 선언된 변수로 선택됨
한번에 여러 개의 옵셔널 타입을 바인딩 할 수도 있음
let optionalNumber: Int? = nil
guard let nonOptionalNumber = optionalNumber else {
//the 'optionalNumber' is nil
return
}
옵셔널 바인딩 guard let 매커니즘
① 표현식이 nil인지 아닌지 판별하자
② 표현식이 nil이 아닌 경우
guard문은 guard문 밖에서 사용 가능함
! 주의 !
옵셔널 바인딩된 nonOptionalNum의 Scope는 guard 구문 밖임
따라서 else문에서는 nonOptionalNum을 사용할 수 없음
③ 표현식이 nil인 경우
이렇게 else 구문으로 빠져서 return을 때리거나 실행을 종료하는 것이 일반적임!
💡. TIP
Non Optional Type의 이름
guard문은 함수(메서드)의 매개변수로 들어온 표현식에 한해서만 똑같이 쓰는 것 가능함
⭕️ 가능한 경우
함수(메서드)로 넘어온 파라미터 값 (임시 상수 혹은 변수)을 바인딩 할 경우
❌ 불가능한 경우
함수(메서드) 내에서 선언한 상수 혹은 변수를 바인딩 할 경우
한번에 여러 개의 옵셔널 타입을 바인딩 할 수도 있음, 옵셔널 바인딩을 하나의 gurad문에서 연속으로 할 수도 있고, condition을 넣을 수 있음
🍏 if let
단순히 옵셔널 처리 값에 대한 피드백만 주고 싶을 때
너 값 있으면 이렇게 처리하고 nil 이면 저렇게 처리해!
🍎 guard let
옵셔널 처리 값이 nil인 경우 무조건 함수의 실행을 종료 시킬 때
너 값 없니? 그럼 내 함수에서 나가
Optional Expression ?? Non-Optional Expression
let name: String? = "Joohee"
자 Optional String Type인 name이 있음
이때,
name이 nil이 아닐 경우 -> hello, (name)
name이 nil일 경우 -> hello, what's your name?
if let name = name {
print("hello, \(name)")
} else {
print("hello, what's your name?")
}
이렇게 구현 해야함
print("hello, " + (name ?? "what's your name?"))
한줄로 연산이 끝나게 됨!!!!
① name에 값이 있을 경우
② name에 값이 없을 경우 (nil)
! 주의 !
Nil-Coalescing에 사용되는 Optional Type과 Non-Optional Type은
Optional을 제외하면 동일한 Type이어야 함
ex)
-- 이것도 잘 사용하지 않기에.. 필요해지면 더 공부해보고 정리하겠음!