옵셔널타입 기본 개념
nil - 값이 없음을 표현하는 키워드(실제 값이 없음이 아님)
nil은 실제 값이 없는 것이 아니고, "값이 없음을 의미한다"고 한단계 쌓여있는 것
다른 언어에서는 null이라고 많이 표현(그러나 스위프트에서는 실제 값이 없는 것이 아님)
옵셔널 타입(Optional Type)
모든 타입의 뒤에 ? 물음표를 붙이면 옵셔널 타입이 된다.
var num: Int? = 3
var yourAge: Int? = nil
var yourGrade: Double? = nil
var name1: String? = "Jobs"
num = nil
name1 = nil
값이 없어도 되는 타입으로 선언 했기 때문에, 값이 없어도 괜찮음
옵셔널, 옵셔널 타입의 기본 개념에 대한 이해
메모리 공간에 "임시적인 타입"을 넣어놓으면 어떨까?
var optionalName: String?
print(optionalName) // 에러가 나지 않음 (옵셔널은 값이 없다는 것을 나타내는 키워드)
nil 출력
옵셔널 타입 선언의 기본 규칙
- 1) nil 대입 가능
- 2) 자동 초기화 (값을 넣지 않을 시에 nil로 초기화)
정식문법 표기
let num1: Int? = 2 // 간편표기
let num2: Optional<Int> = 0 // 정식문법
옵셔널타입 연습
//var optionalNum = nil // 불가능한 형태
var optionalNum: Int? = nil // (추론할 형식이 없기 때문에 반드시 타입 어노테이션으로 초기화해야됨)
optionalNum = 10
// 값이 없을 수도 있는 (임시적인)타입
print(optionalNum) // 출력값: Optional(10)
let str: String = "Swift"
var optionalStr: String? = nil //옵셔널 스트링 타입 ====> (값이 없을 수도 있는 타입이다)
옵셔널타입은 반드시 변수로 선언해야함. 값이 들어갈 수 있으려면 값이 변해야하기 때문에
var a: Int? = 7 // 옵셔널 인트
var b = a // 값을 복사해서 담는 다면 타입은?
print(b) // 출력값: Optional(7)
var c: Int = 5
b = c // Int를 Int?타입에 담을 수는 있다. (어쨌든 타입이 Int? 타입으로 바뀌어서 담김)
print(b) // 출력값: Optional(5)
옵셔널 타입끼리의 연산은 불가능
옵셔널값의 추출 방법
옵셔널 타입: 값이 없을 수도 있는 경우를 포함하는(감싸고) 있는 임시적 타입
var num: Int?
var str: String? = "안녕하세요"
print(num) // nil
print(str) // Optional("안녕하세요")
옵셔널값을 추출하는 4가지 방법
1) 강제로 값을 추출(Forced Unwrapping): 값이 있다는 것이 확실할때 사용
print(str!)
//print(num!) // 에러
강제 추출연산자 !를 옵셔널표현식 뒤에 붙여서 강제로 옵셔널값을 추출
2) if문으로 nil이 아니라는 것 확인한 후, 강제로 벗기기
if str != nil {
print(str!)
}
3) 옵셔널 바인딩 (if let 바인딩) ⭐️
옵셔널 바인딩 - 바인딩이 된다면, 특정 작업을 하겠다는 의미
if let s = str { // s라는 상수에 담긴다면 (안에 값이 있다면) // 안담긴다면 nil
print(s)
}
실제 앱을 만들때 guard let 바인딩 많이 사용
func doSomething(name: String?) {
guard let n = name else { return } // 값이 있는 경우에만 n에 담고 실행
print(n)
}
doSomething(name: "hello") // 출력값: hello
값을 우아하게 벗기는 방법
4) 닐 코얼레싱 (Nil-Coalescing) 연산자를 사용하는 방법
(코얼레싱(coalesce): 영어로 (더 큰 덩어리로) 합치다는 뜻
var serverName: String? = "홍길동"
var userName = serverName ?? "미인증사용자" // String타입
옵셔널 타입에 대하여, 디폴트(기본)값을 제시할 수 있을 때 사용
(직접 값을 벗겨서 사용하는 것은 아니고, 디폴트값 제시를 통해 옵셔널 가능성을 없애는 방법)
var hello = "인사하겠습니다. " + (str ?? "Say, Hi")
print(hello) // 출력값: 인사하겠습니다. 안녕하세요
삼항연산자랑 비슷함
옵셔널 타입(임시 타입)을 추출하는 방법 4가지 + 옵셔널 체이닝(Chaining) 표
Unwrapping 방법
방법 | 설명 | 경우 |
1) 강제 추출 (Forced Unwrapping) |
nil이 아닌 값이 있다는 것을 확신하고 강제로 값을 추출 (값이 없는 경우 에러) | |
2) nil 아닌지 확인 후, 강제 추출 | if문을 통해 nil이 아님을 먼저 확인 후, 강제 추출 (에러 가능성이 없어짐) | |
3) 옵셔널 바인딩 (if let / guard let 바인딩) |
바인딩(상수나 변수에 대입)이 되는 경우만 특정 작업을 하겠다는 의미 | 일반적인 경우 |
4) Nil-Coalescing (닐 코얼레싱) | 옵셔널 표현식 뒤에 기본값을 제시해서, 옵셔널의 가능성을 없앰 | 디폴트값 제시가능한 경우 |
접근연산자 사용시
방법 | 설명 | 경우 |
옵셔널 체이닝 | 표현식 자체가 옵셔널의 가능성이 있다는 것을 표현. 체이닝의 결과는 항상 옵셔널 (옵셔널 타입에 대해 접근연산자 사용은 항상 ?를 붙임) |
Unwrapping 후 사용해야 함 |
옵셔널 체이닝과 IUO 타입은 다음번에...
함수와 옵셔널타입
옵셔널 파라미터 사용 함수의 정의
func doSomePrint(with label: String, name: String? = nil) { // String? = nil
print("\(label): \(name)")
}
함수의 실행
// doSomePrint(with: String, name: String?)
doSomePrint(with: "레이블", name: "스티브 잡스")
doSomePrint(with: "레이블", name: nil)
doSomePrint(with: "레이블")
일반적으로는 String? = nil (기본값까지 설정해서, 함수를 유연하게 사용하도록 함)
유연함 ==> 굳이 아규먼트를 안 넣어서 사용해도 됨
애플이 미리 만들어 놓은 함수/메서드에는 파라미터가 옵셔널타입과 기본값이 nil로 설정된 함수들이 많음 유의!
'iOS 관련 공부' 카테고리의 다른 글
딕셔너리 / 해셔블(Hashable) (0) | 2025.01.31 |
---|---|
컬렉션(Collection) - 배열 (0) | 2025.01.24 |
inout 파라미터, guard문, @discardableResult (0) | 2024.12.31 |
함수의 응용, 함수 사용시 주의점 (0) | 2024.12.26 |
함수의 형태 (0) | 2024.12.24 |