안녕하세요 ! kyuu 입니다 :)
오늘은 Optional 과 nil 을 살펴보도록 하겠습니다 ^^
자 오늘은 스위프트에서 아주 중요한 옵셔널 타입을 어떻게 다룰 것인지 알아볼 거에요
옵셔널 바인딩, 언래핑, 옵셔널 체인 강제 언래핑을 이용한 옵셔널 다루는 방법을
다뤄보려고 합니다 ! 이번 글은 T아카데미 프로그래밍 강의 영상을 참고하여 작성하였습니다
Optional 옵셔널
- 일반 변수/ 상수 : nil 대입 불가
- 옵셔널 타입 : nil을 다룰 수 있는 타입
- 타입 뒤에 (?) 로 선언
- 타입 선언 필수
var optionalVar : Optional<Int>
var optionalVar2 : Int?
자 이런 식으로 선언하면은 정수형을 다룰 수 있고 그리고 nil이 될 수 있습니다.
그렇지만 축약된 표현으로는 밑에 optionalvar2 처럼 많이 사용합니다 자 만약에 string 타입이 필요하면
뒤에 (?)를 작성하여 문자열을 다루는 변수이지만 nil 도 다룰 수 있는 Optional 타입을 선언할 수 있습니다.
자 옵셔널 타입의 특징은 아래 코드를 통해 살펴볼게요!
옵셔널 타입의 특징
- nil 대입 가능
var optionalVar : Int? = 3
optionalVar = nil
- 자동 초기화
var optionalVar : Int?
print(optionalVar)
콜렉션과 옵셔널
옵셔널이 콜렉션에서 어떻게 사용되는지
한번 알아볼게요!
여기서는 물음표 기호가 어디에 들어가냐에 따라서 조금 다르게 동작합니다.
배열에 옵셔널을 선언해 보겠습니다
아래 코드를 통해서 봐주세요!
var array1 : [String]?
var array2 : [String?]
array1 같은 경우는 배열 자체가 옵셔널입니다 즉 배열이 없을 수도 있고 nil 이 될 수도 있고 배열이 있을 수도 있습니다.
array2 같은 경우에는 배열 안에 물음표가 들어가 있죠? 이러면 배열 자체는 옵셔널이 아닙니다 그렇기 때문에 배열은 반드시 유효한
형태에 배열이 있어야 됩니다. 딕셔너리도 마찬가지입니다! 딕셔너리는 추후에 제가 업로드하겠습니다 자 이런 식으로
컬렉션은 타입의 어느 부분에 옵셔널이 들어가는에 따라서 의미가 좀 달라진다는 점을 주의하셔야 합니다.
객체 데이터 다루기
- 객체나 데이터를 이용한 함수, 프로퍼티, 첨자 접근
- 유효한 객체나 유효한 값에서 정상 동작
- nil에서는 - 비정상 동작
옵셔널 타입 사용
- 옵셔널 타입의 객체는 nil일 수도 있다.
- 그래서 옵셔널 타입 객체는 다른 사용 방법
- nil 인 경우와 nil이 아닌 경우 고려 !! 중요
옵셔널 타입의 객체 사용
- 옵셔널 타입 : nil 이거나 혹은 유효한 값
- 언래핑 : 옵셔널 타입의 변수에서 유효한 값 얻어오기
- nil 여부 비교, 옵셔널 바인딩
- 옵셔널 체인
- 강제 언래핑
먼저 nil 검사하는 방법에 대해 살펴보겠습니다.
자 이렇게 nil 여부를 판단하기 위해서 if 문이나 guard 문을 사용할 때 주의할 점은
!= , == 이 조건을 생략할 수 없습니다.
var optionalStr : String?
if optionalStr != nil {
print("nil이 아니다")
} else {
print("nil이다")
}
옵셔널 바인딩 (Optional Binding)
if / guard 와 함께 사용하는고 거기서 유효한 값을 얻어오는 걸 옵셔널 바인딩이라고 합니다.
유효한 값을 얻어와서 상수에 대입해서 if / guard 바디 안에서는 Non_Optinal 로 동작하는 게 옵셔널 바인딩이 됩니다.
그러면 nil인 경우는 else로 동작해서 nil인 경우에 대한 동작들을 따로 처리해 줄 수 있습니다.
그럼 코드를 통해 살펴볼게요!
func printName(_name : String) {
print(_name)
}
var myName: String? = nil
//myName 상자에 값이 있으면 name에 myName을 넣어주고 조건을 실행해
if let name = myName {
printName(_name: name)
}
myName 상자에는 nil이 있어서 if let 구문은 멈추고 실행을 하지 않는 것입니다. 값이 있을 때만 값이 바인딩 되기 때문이죠
이것을 옵셔널 바인딩이라고 부릅니다.
옵셔널 체이닝 (Optional Chaining)
옵셔널 체이닝을 이해하는 데에는 설명 보단 코드를 보는 것이 좋습니다!
간단히 설명드리자면
옵셔널 객체에다가? 기호를 사용해서 직접 사용합니다 체인이기 때문에 연달아서 사용이 가능합니다.
옵셔널 체인을 물음표를 이용해서 평가를 하는데 그 평가에 대한 결과가 중간에라도 nil 이면 그 이후를 진행하지 않고
nil 이 반환됩니다. 그렇지만 평가 결과가 nil이 아니라면 계속해서 진행합니다(언래핑) 결국 최종 결과는 옵셔널 타입이 됩니다.
옵셔널 체인은 메소드 호출, 프로퍼티 접근, 배열 원소 접근을 할 때 사용이 가능합니다
var optionalStr : String? = "ABC"
let str = optionalStr?.lowercased()
str // 결과는 옵셔널 Optional("abc")
자 이번에는 값이 nil인 경우입니다 똑같이 옵셔널 체인을 사용하고 첫 번째 평가 결과를 보고
그 이후를 실행하지 않고 nil을 반환 합니다.
optionalStr = nil
let str2 = optionalStr?.lowercased() // lowercased() 진행안함
str2 // 결과는 nil
옵셔널 체이닝은 제가 배열 접근을 할 때도 가능하다고 말씀드렸죠?
배열 자체에 옵셔널이기 때문에 첫 번째 원소에 접근하는 행위가 nil 인지 아닌지 판단해야 됩니다.
자 그래서 배열이 nil 이면 nil이 반환되고 그게 아니라면 평가가 돼서 1이면 b가 되겠죠?
코드를 통해서 볼게요!
let array : [String]? = ["A","B","C"]
let str3 = array?.[1].lowercased() // b
암시적인 언래핑 옵셔널 (Implicitly Unwrapped Optional)
타입에다가 ! 를 붙여서 만드는 타입입니다.
코드를 통해서 설명드리겠습니다
var name: String! = "kyuu"
print(name) // kyuu
이런 식으로 정의된 옵셔널은 nil 을 포함할 수 있는 옵셔널이 될 수도 있지만 접근할 때 옵셔널 바인딩이나 옵셔널을 벗기는 과정을
거치지 않고도 바로 값에 접근할 수 있다는 점에서 일반적인 옵셔널과 조금 다릅니다.
var name: String! = "kyuu"
name = nil // nil 을 대입해도 에러가 나지않음
-----------------------------
var name: String! = "kyuu"
name.append("!!!") // kyuu!!! // 자동으로 언래핑되서 사용이 가능
만약 값을 nil 로 변경 후에 append를 해도 역시 nil 이기 때문에 에러가 납니다 옵셔널을 가급적이면
일반적인 옵셔널을 사용해서 정의한 후에 옵셔널 바인딩,체이닝을 통해 값에 접근하는 것이 더 안전합니다!
강제 언래핑 (Forced Unwrapping)
언래핑이란? 옵셔널 타입에 객체에서 유효한 값을 가져오는 것을 언래핑이라고 합니다
자 그것을 강제로 하는 방법입니다.
! 기호를 사용합니다 그리고 nil 여부와 관계없이 무조건 언래핑을 시도합니다
타입 선언이나 옵셔널 체인에도 사용이 가능합니다.
강제 언래핑 결과는 nil 이면 에러가 납니다 nil 이 아닌 경우에는 성공적인 언래핑이 됩니다.
let intVal2 = Int("1")!
이런 경우에는 반환되는 타입은 옵셔널 Int가 아니고 그냥 Int 타입이 됩니다
강제 언래핑 사용하는 경우는 언제가 있을까요?
객체 생성을 할 때나 메소드 호출, 프로퍼티
접근 옵셔널 체인에서도 ? 대신 ! 를 이용해서 강제 언래핑을 사용하실 수 있습니다.
딕셔너리 코드를 통해 같이 살펴보겠습니다.
let dictionary = ["one":,
"two":2]
let two = dictionary["two"]!
// 2 정상적인 값 출력
이번엔 딕셔너리에 없는 three에 접근했습니다. 그렇지만 three가 없죠?
그래서 강제언래핑을 하지 않았을 때는 nil이 반환됩니다. 앱이 죽진 않습니다 그렇지만 ! 를 붙이게 되면
nil에 대해서 언래핑을 시도했기 때문에 에러가 납니다 그래서 앱 자체가 크래시가되서 강제 종료가 될 수도 있습니다
그렇기 때문에 강제 언래핑은 주의해서 사용하셔야 합니다!
// 언래핑 실패
let three = dictionary["three"]!
강제 언래핑을가지고 옵셔널 체인을 사용하는 방법도 살펴보도록 하겠습니다!
여기서 결과는 ABC에 대한 옵셔널 타입이 아닌 여기서는 유효한 값에 abc가 반환이 됩니다.
var optionalStr: String? = "ABC"
let str1 = optionalStr!.lowercased()
//abc
자 이렇게 옵셔널에 대해 알아보았는데요 정말 많이 써 내려갔네요..하하 옵셔널은 개발할때 매우 많이 쓰인다고합니다
길고 긴 글 읽어주셔서 감사합니다! 틀린 부분이 있다면 지적해 주세요!! 감사합니다
'Swift > 문법 정리' 카테고리의 다른 글
SwiftUI에서 속성 래퍼(@State, @Binding, @ObservedObject, @EnvironmentObject) 이해하기 (3) | 2023.05.31 |
---|---|
Swift: 기초문법 ( if / switch ) , ( for / while ) 조건문과 반복문 제어문(3) (1) | 2022.04.27 |
Swift : 기초 문법 [ Data Type : 데이터 타입 ] (2) (1) | 2022.03.15 |
Swift : 기초 문법 [ 변수와 상수] (1) (0) | 2022.03.13 |