Swift의 온도

Swift #6 - nil과 옵셔널

IT의 온도 2021. 1. 8. 01:29

 

1. nil과 옵셔널 타입

 

- nil

#다른 언의 null에 해당

#값이 할당되지 않은 상태

#기본 타입(Int, Bool)에도 nil 가능

#값이 0과 값이 nil

 

- 옵셔널 타입

#일반 변수/상수 : nil 대입 불가

#옵셔널 타입 : nil을 다룰 수 있는 타입

 

- nil 대입

#변수/상수에 nil 대입

 *일반 변수(상수)는 nil이 될 수 없다

 *일반 변수에 nil대입 - 에러

 

- 옵셔널

#옵셔널 타입
 *nil 값이 될 수 있는 변수/상수
 *타입 뒤에 물음표(?)로 선언
 *타입 선언 필수
 
var optionalVar : Optional<Int>
var optionalVar2 : Int?
 
#옵셔널 타입의 특징
 *nil 대입 가능
 
var optionalVar : Int= 3
optionalVar = nil
 
 *자동 초기화
 
var optionalVar : Int?
print(optionalVar) // nil
cs

 

- nil 결과

#결과가 nil이 되는 행위

 *동작 결과가 nil 가능

 *결과 타입이 옵셔널 타입

 *타입변환

let intFromStr = Int("a")
intFromStr // Int?
cs

 *딕셔너리

let numbers = ["one":1"two":2]
let three = numbers["three"]
cs

 

- 콜렉션과 옵셔널

*배열
 
var array1 : [String]?
var array2 = [String?]
 
*딕셔너리
 
var dic1 = [String : Int]?
var dic2 = [String : Int?
cs

 

2. 옵셔널 타입 사용하기

 

- 옵셔널 사용

#객체나 데이터 다루기

 *객체나 데이터를 이용한 함수, 프로퍼티, 첨자 접근 등

 *유효한 객체나 유효한 값에서 정상 동작

 *nil에서는 - 비정상 동작

 

#옵셔널 타입 사용

 *옵셔널 타입의 객체는 nil일 수도 있다.

 *그래서 옵셔널 타입 객체는 다른 사용 방법

 *nil인 경우와 nil아닌 경우 고려

 

- 옵셔널 타입의 객체 사용

#옵셔널 타입 : nil 이거나 혹은 유효한 값

#언래핑 : 옵셔널 타입의 변수에서 유효한 값 얻어오기

#nil 여부 비교, 옵셔널 바인딩

#옵셔널 체인

#강제 언래핑

 

- nil 검사하기

*if, guard
 
var optionalStr : String?
if optionalStr != nil {
    print("nil이 아니다!")
}
else {
    print("nil이다")
}
 
*조건문 작성하기 : != nil, == nil 조건 생략 불가
 
if optionalVal {
}
cs

 

- 옵셔널 바인딩

#if/guard 와 함께 사용

#옵셔널 타입에서 유효한 값을 상수에 대입

#바인딩 된 타입은 일반(Non-Optional) 타입

#nil인 경우 else로 동작

*if를 이용한 옵셔널 바인딩
 
if let realStr = optionalStr {
    print("문자열의 값\(realStr)")
}
else {
    print("문자열이 nil이다");
}
cs

 

- 옵셔널 바인딩 : guard

*바인딩 된 상수의 범위(scope)
 
func bindingWithWhere() {
    guard let val = nilAvailable, val > 0 else {
        return;
    }
    print("val은 유효하고 0보다 큰 값이다\(val)")
}
cs

 

*다중 바인딩, 함수 호출(옵셔널 타입 변환)
 
if let val1 = someFunc(),
   let val2 = anotherFunc() {
    //코드
}
 
*옵셔널 바인딩 체인
 
if let val1 = nilAvailableStr,
   let val2 = Int(val1) {
    // 코드
}
 
*옵셔널 바인딩과 조건 비교
 
if let val = someFunc(). condition == true {
    //코드
}
cs

 

 

- nil 연산자

#nil 연산자 : ??

 *nil이면 ?? 연산자 이후의 값 아용

 *기본값 설정으로 활용 가능

var userSelectedColor : String?
//nil이면 Red를 사용
var colorName = userSelectedColor ?? "Red"
cs

 

-  옵셔널 체인

#옵셔널 객체에 ?기호를 이용해서 직접 사용

#평가 결과가 nil이면 진행하지 않고 nil 반환

#평가 결과가 nil이 아니면 계속 진행(언래핑)

#최종 결과는 옵셔널

#메소드 호출, 프로퍼티 접근, 배열 원소 접근 등

*유효한 값인 경우
 
var optionalStr : String= "ABC"
 
let str = optionalStr?.lowercased()
str // 결과는 옵셔널 Optional("abc")
 
*nil인 경우
 
optionalStr = nil
 
let str2 = optionalStr?.lowercased() // lowercased() 진행 안함
str2 // 결과는 nil
cs
*프로퍼티 접근/메소드 호출/배열, 딕셔너리 접근 등
 
let array : [String]? = ["A""B""C"]
let str3 = array?[1].lowercased()
cs

 

3. 강제 언래핑

 

#기호사용

#nil 여부와 관계 없이 언래핑 시도

#타입 선언이나 옵셔널 체인에 사용

#언래핑 결과

 *nil 이면 에러

 *nil 이 아니면 언래핑

*옵셔널 객체 반환 - Int? 타입 객체 반환
 
let inVal1 = Int("1")
 
*강제 언래핑 - Int 타입 객체 반환
 
let intVal2 = Int("1")!
cs

 

- 강제 언래핑 사용 사례

 *객체 생성(Failable Initializer)

 *메소드 호출, 프로퍼티 접근

 *옵셔널 체인

 

- 강제 언래핑 사용 예

*강제 언래핑 시도 - nil이면 런타임 에러 - 주의!
*변환 실패
 
let val = Int("A")! // Error
 
*딕셔너리 원소 접근 - 언래핑 성공
 
let dictionary = ["one":1"two":2]
let two = dictionary["two"]!
 
*언래핑 실패 - 에러 발생
 
let three = dictionary["three"]!
cs

 

- 강제 언래핑과 옵셔널 체인

#옵셔널 체인에 강제 언래핑 사용

#언래핑 실패 시 런타임 에러

var optionalStr : String= "ABC"
let str1 = optionalStr!.lowercased()
cs

 

- 암시적 언래핑 옵셔널

#Implicitly Unwrapping Optional, IUO

#타입 선언 뒤에 !

#nil 다루기 가능

#nil로 자동 초기화

#자동으로 언래핑

var iuoVal : int! = 123
iuoVal = nil
cs

#암시적 언래핑 옵셔널 사용하기

*?, ! 기호 없이 직접 사용 가능
 
let iuoStr : String! = "Hello, Swift"
iuoStr.lowercased()
 
*nil인 경우 런타임 에러 - 주의
 
iuoStr = nil
iuoStr.lowercased()
cs