일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- html
- 맥북
- wwdc 2020
- 아이폰12
- AWS
- 루메나
- Mac
- Iphone 12
- EC2
- 타임머신
- TimeMachine
- LG V20
- 맥북프로
- 샤오미
- iphone
- 웹 프로그래밍
- 맥
- mysql
- 27UP850N
- iOS 14
- V20
- 오난코리아
- 프론트
- 코딩
- Fan Pro 3세대
- 애플
- macbook
- 휴대용 선풍기
- LUMENA
- It
- Today
- Total
이것저것 적어보는 블로그
Swift 옵셔널(Optional) 본문
Swift를 공부하면서 매번 제대로 정리가 안되는 개념이 있는데 바로 옵셔널(Optional)이다.
그래서 이참에 포스팅하면서 정리해두려고 한다.
옵셔널이란 변수의 값이 있을 수도 있고 없을 수도 있다는걸 나타낸다.
불편해보이는 Optional 왜 사용할까 싶은데
Objective-C에 아직 nil타입이 존재하며, 프로젝트에서 obj-c와 swift를 혼용해서 사용할 수 있어 obj-c와 상호운용성을 위해 사용한다고 한다.
옵셔널이 필요한 이유 -> nil의 가능성을 명시적으로 표현
Type casting, nil value 체크 등에 있어서 중요한 역할
- nil 가능성을 문서화 하지 않아도 코드만으로 충분히 표현가능
- 문서 / 주석 작성 시간을 절약
- 전달 받은 값이 옵셔널이 아니라면 nil체크를 하지 않더라도 안심하고 사용
- 효율적인 코딩
- 예외 상황을 최소화하는 안전한 코딩
옵셔널이 아닌 상수에다가 nil값을 할당 시 컴파일 오류 발생
옵셔널은 열거형과 제너럴의 합작품. 아래와 같이 선언이 되어 있다.
enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
}
let optionalValue: Optional<Int> = nil
let optionalValue: Int? = nil
var optionalValue: Optional<Int> = 100 (완전한 문법)
var optionalValue: Int? = 100 (간략한 표현)
! - Implicitly Unwrapped (암시적 추출 옵셔널)
var optionalValue: Int! = 100
// 기존 변수처럼 사용 가능
optionalValue = optionalValue + 1
// nil 할당 가능
optionalValue = nil
// 잘못된 접근으로 인한 런타임 오류 발생, optionalValue에 nil이 들어가 있기 때문!
optionalValue = optionalValue + 1
? - 일반적인 옵셔널
var optionalValue: Int? = 100
// nil 할당 가능
optionalValue = nil
// 기존 변수처럼 사용불가 - 옵셔널과 일반 값은 다른 타입이므로 연산불가
optionalValue = optionalValue + 1
Optional Unwrapping, 옵셔널을 꺼내는 방법은 2가지 방법이 있다.
먼저, Optional Binding(옵셔널 바인딩)
nil체크 + 안전한 값 추출을 하는 방식으로, 옵셔널에 값이 있는 경우에만 값을 추출
if-let/var 방식, guard-let 방식을 이용한다.
// if-let 방식
func printName(_ name: String) {
print(name)
}
var myName: String? = nil
//printName(myName)
// 전달되는 값의 타입이 다르기 때문에 컴파일 오류발생
if let name: String = myName {
printName(name)
} else {
print("myName == nil")
}
// name 상수는 if-let 구문 내에서만 사용가능합니다
// 상수 사용범위를 벗어났기 때문에 컴파일 오류 발생
//printName(name)
힌번에 하나만 바인딩 가능한게 아닌 여러개 동시에도 가능합니다.
myName = "yagom"
yourName = nil
if let name = myName, let friend = yourName {
print("\(name) and \(friend)")
}
// yourName이 nil이기 때문에 실행되지 않습니다
yourName = "hana"
if let name = myName, let friend = yourName {
print("\(name) and \(friend)")
}
// yagom and hana
guard-let은 if-let과 비슷하지만, else인 부분만 작성이 가능하다.
값이 nil이여서 옵셔널이 추출되지 않은 경우만 어떠한 액션이 가능!
guard-let을 통과한 경우 저장된 상수는 전역변수로 사용 가능!!
guard-let의 else문 안에는 항상 return 아니면 throw문이 와야 한다.
// guard-let 방식
func optbinding(){
guard let name_m: String = myName else {
return print("myName is Optional")
}
print(name_m)
guard let name_y: String = yourName else {
return print("yourName is Optional")
}
print(name_y)
}
optbinding()
Force Unwrapping (옵셔널 강제 추출)
옵셔널 변수명 + !, 그다지 추천되는 방식은 아니다
printName(myName!) // yagom
myName = nil
// print(myName!)
// 강제추출시 값이 없으므로 런타임 오류 발생
var yourName: String! = nil
//printName(yourName)
// nil 값이 전달되기 때문에 런타임 오류발생
'개발&코딩 > Swift' 카테고리의 다른 글
Swift Strong과 Weak 그리고 Unowned (0) | 2022.10.09 |
---|---|
Swift 변수명 규칙 (0) | 2022.10.08 |
Swift 함수 기본 문법 (0) | 2020.12.27 |