옵셔널
변수 뒤에 붙는 ? 물음표가 바로 옵셔널이다.
옵셔널 변수는 값이 있을 수도 또는 없을 수도 있다는 의미이다.
name이라는 변수에 String 타입으로 "jerry"라는 값을 할당했다.
var name: String = "jerry"
print(name)
// jerry
근데 만약에 name이라는 변수에 들어갈 값이 아직 정해지지 않았다면?
String 타입 뒤에 ? 물음표를 붙인다.
그러고 print()로 출력하면 nil이 출력된다.
var name: String?
print(name)
나중에 name이라는 변수에 값을 할당한다면?
그리고 출력하면 Optional("jerry")가 나온다.
var name: String? = "jerry"
print(name)
// Optional("jerry")
Optinal()로 감싸져서 나온 값이랑 그렇지 않은 값은 연산이 가능한가?
그렇지 않다.
예를 들어 Int 타입의 두 변수 중 하나는 옵셔널로 선언할 경우
두 변수의 연산은 안된다.
오류가 뜨는데 옵셔널 타입을 해제해야 한다고 한다.
Optional() 해제
1. Force Unwrapping (강제 해제)
변수명 뒤에 ! 느낌표를 붙여준다. (추천하지 않음)
var name: String?
print(name!)
이 경우에 nil이 출력된다.
다만, Expression implicitly coerced from ‘String?’ to ‘Any’ 라는 warning 이 뜨게 되는데
이 경우에는 nil일 경우에 대비한 기본값을 할당하면 된다.
var name: String?
print(name ?? "이름 없음")
2. Optional Binding
강제 해제는 오류가 발생할 위험이 있기 때문에 추천하지 않는다.
안전하게 값에 접근하기 위해서는 Optional Binding을 쓴다.
- if let
- guard let
if let 을 이용하여 Optional Binding 하는 경우
name 이라는 옵셔널로 선언한 변수에 "jerry" 라는 값을 할당했다.
함수 checkName 안에 if let을 이용하여 옵셔널 바인딩을 처리했다.
var name: String? = "jerry"
func checkName(name: String?) {
if let checkName = name {
print("이름 : \(checkName)")
} else {
print("없음")
}
}
checkName(name: name) // 이름 : jerry
name 이라는 변수에 값이 없었다면 "없음"이라고 출력된다.
var tom: String?
checkName(name: tom) // 없음
guard let 을 이용하는 경우
guard let은 함수에서만 사용할 수 있기 때문에 함수로 만들어 사용한다.
guard의 조건을 만족하지 못하면 else 구문 블럭 내의 print() 와 return을 반환하고,
만족하면 print() 출력한다.
var apple: String? = "Apple"
var banana: String = "banana"
var kiwi: String?
func checkFruit(name: String?) {
guard let fruitName = name else {
print("과일 이름 없음")
return
}
print("과일 이름: \(fruitName)")
}
checkFruit(name: apple) // 과일 이름: Apple
checkFruit(name: banana) // 과일 이름: Banana
checkFruit(name: kiwi) // 과일 이름 없음
- if let: 값의 유무를 확인 후, 있을 때 없을 때 각각의 코드를 실행
- guard let: 값의 유무를 확인 후, 값이 없으면 함수를 실행하지 못하도록 방어
- 복잡도: if let > guard let
'Swift > 기본' 카테고리의 다른 글
클래스 (Class) (0) | 2024.04.01 |
---|---|
구조체 (Struct) (0) | 2024.04.01 |
반복문 (0) | 2024.03.26 |
조건문 (0) | 2024.03.26 |
함수 고급 (0) | 2024.03.22 |