반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- JPA
- AI
- 42seoul
- 프로그래밍언어론
- CI
- 다이어리
- DBMS
- 리눅스
- javascript
- 스프링부트 웹 소켓
- MySQL
- 스프링부트
- IOS
- springboot
- 티스토리챌린지
- libasm
- 스프링
- 아이패드다이어리
- 네트워크
- jenkins
- 인공지능
- 데이터베이스
- Xcode
- 오블완
- swift
- CD
- Spring
- 소켓
- 오라클
- sql
Archives
- Today
- Total
Hi yoahn 개발블로그
[Swift] #6 다양한 표현 및 확장 4 (옵셔널체이닝/nil 병합/타입캐스팅) 본문
반응형
1. 옵셔널 체이닝
- 옵셔널 체이닝은 옵셔널의 내부의 내부의 내부로 옵셔널이 연결되어 있을 때 유용하게 활용할 수 있습니다.
- 매번 nil 확인을 하지 않고 최종적으로 원하는 값이 있는지 없는지 확인할 수 있습니다.
// 예제 클래스
// 사람 클래스
class Person {
var name: String
var job: String?
var home: Apartment?
init(name: String) {
self.name = name
}
}
// 사람이 사는 집 클래스
class Apartment {
var buildingNumber: String
var roomNumber: String
var `guard`: Person?
var owner: Person?
init(dong: String, ho: String) {
buildingNumber = dong
roomNumber = ho
}
}
// 옵셔널 체이닝
let yagom: Person? = Person(name: "yagom")
let apart: Apartment? = Apartment(dong: "101", ho: "202")
let superman: Person? = Person(name: "superman")
// 옵셔널 체이닝이 실행 후 결과값이 nil일 수 있으므로
// 결과 타입도 옵셔널입니다
// 만약 우리집의 경비원의 직업이 궁금하다면..?
// 옵셔널 체이닝을 사용하지 않는다면...
func guardJob(owner: Person?) {
if let owner = owner {
if let home = owner.home {
if let `guard` = home.guard {
if let guardJob = `guard`.job {
print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
print("우리집 경비원은 직업이 없어요")
}
}
}
}
}
guardJob(owner: yagom)
// 옵셔널 체이닝을 사용한다면
func guardJobWithOptionalChaining(owner: Person?) {
if let guardJob = owner?.home?.guard?.job {
print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
print("우리집 경비원은 직업이 없어요")
}
}
guardJobWithOptionalChaining(owner: yagom)
// 우리집 경비원은 직업이 없어요
yagom?.home?.guard?.job // nil
yagom?.home = apart
yagom?.home // Optional(Apartment)
yagom?.home?.guard // nil
// 경비원 할당
yagom?.home?.guard = superman
yagom?.home?.guard // Optional(Person)
yagom?.home?.guard?.name // superman
yagom?.home?.guard?.job // nil
yagom?.home?.guard?.job = "경비원"
if let guardJob = owner?.home?.guard?.job
owner 가 nil 이 아니면 -> home 이 nil 이 아니면 -> guard 가 nil 이 아니면 -> job
체크하다가 중간에 하나라도 nil 이 나오면 멈추고 바로 nil 반환
2. nil 병합 연산자
- 중위 연산자입니다. ??
- Optional ?? Value
- 옵셔널 값이 nil일 경우, 우측의 값을 반환합니다.
- 띄어쓰기에 주의하여야 합니다.
var guardJob: String
guardJob = yagom?.home?.guard?.job ?? "슈퍼맨"
print(guardJob) // 경비원
yagom?.home?.guard?.job = nil
guardJob = yagom?.home?.guard?.job ?? "슈퍼맨"
print(guardJob) // 슈퍼맨
3. 타입 캐스팅
- 인스턴스의 타입을 확인하는 용도
- 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는지 확인 하는 용도
딕셔너리 사용 시, Any & AnyObject 사용하면 타입캐스팅 많이 사용 - is, as를 사용합니다.
- 방법은 다르지만 개념과 원리는 C++ 과 비슷한것 같다.
타입 캐스팅이 아님
let someInt: Int = 100
let someDouble: Double = Double(someInt)
- someInt 값을 가지고 Double 타입의 인스턴스를 하나 더 생성하는 것
3.1 타입 확인
is
class Person {}
class Student: Person {}
class UniversityStudent: Student {}
var result: Bool
result = yagom is Person // true
result = yagom is Student // false
result = yagom is UniversityStudent // false
result = hana is Person // true
result = hana is Student // true
result = hana is UniversityStudent // false
result = jason is Person // true
result = jason is Student // true
result = jason is UniversityStudent // true
if yagom is UniversityStudent {
print("yagom은 대학생입니다")
} else if yagom is Student {
print("yagom은 학생입니다")
} else if yagom is Person {
print("yagom은 사람입니다")
} // yagom은 사람입니다
/**
* switch 순서에 따라 결과가 달라짐
*/
switch jason {
case is Person:
print("jason은 사람입니다")
case is Student:
print("jason은 학생입니다")
case is UniversityStudent:
print("jason은 대학생입니다")
default:
print("jason은 사람도, 학생도, 대학생도 아닙니다")
} // jason은 사람입니다
switch jason {
case is UniversityStudent:
print("jason은 대학생입니다")
case is Student:
print("jason은 학생입니다")
case is Person:
print("jason은 사람입니다")
default:
print("jason은 사람도, 학생도, 대학생도 아닙니다")
} // jason은 대학생입니다
3.2 업캐스팅
- as를 사용하여 부모클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 타입정보를 전환해줍니다.
- Any 혹은 AnyObject로도 타입정보를 변환할 수 있습니다.
- 암시적으로 처리되므로 꼭 필요한 경우가 아니라면 생략해도 무방합니다.
as
// UniversityStudent 인스턴스를 생성하여 Person 행세를 할 수 있도록 업 캐스팅
var mike: Person = UniversityStudent() as Person
var jenny: Student = Student()
//var jina: UniversityStudent = Person() as UniversityStudent // 컴파일 오류
// UniversityStudent 인스턴스를 생성하여 Any 행세를 할 수 있도록 업 캐스팅
var jina: Any = Person() // as Any 생략가능
3.3 다운캐스팅
- as? 또는 as!를 사용하여 자식 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 인스턴스의 타입정보를 전환해줍니다.
A. 조건부 다운 캐스팅 as?
- as?를 사용합니다.
- 캐스팅에 실패하면, 즉 캐스팅하려는 타입에 부합하지 않는 인스턴스라면 nil을 반환하기 때문에 결과의 타입은 옵셔널 타입입니다.
var optionalCasted: Student?
optionalCasted = mike as? UniversityStudent
optionalCasted = jenny as? UniversityStudent // nil
optionalCasted = jina as? UniversityStudent // nil
optionalCasted = jina as? Student // nil
B. 강제 다운 캐스팅 as!
- as!를 사용합니다.
- 캐스팅에 실패하면, 즉 캐스팅하려는 타입에 부합하지 않는 인스턴스라면 런타임 오류가 발생합니다.
- 캐스팅에 성공하면 옵셔널이 아닌 일반 타입을 반환합니다.
var forcedCasted: Student
forcedCasted = mike as! UniversityStudent
//forcedCasted = jenny as! UniversityStudent // 런타임 오류
//forcedCasted = jina as! UniversityStudent // 런타임 오류
//forcedCasted = jina as! Student // 런타임 오류
사용법
func doSomethingWithSwitch(someone: Person) {
switch someone {
case is UniversityStudent:
(someone as! UniversityStudent).goToMT()
case is Student:
(someone as! Student).goToSchool()
case is Person:
(someone as! Person).breath()
}
}
doSomethingWithSwitch(someone: mike as Person) // 멤버쉽 트레이닝을 갑니다 신남!
doSomethingWithSwitch(someone: mike) // 멤버쉽 트레이닝을 갑니다 신남!
doSomethingWithSwitch(someone: jenny) // 등교를 합니다
doSomethingWithSwitch(someone: yagom) // 숨을 쉽니다
func doSomething(someone: Person) {
if let universityStudent = someone as? UniversityStudent {
universityStudent.goToMT()
} else if let student = someone as? Student {
student.goToSchool()
} else if let person = someone as? Person {
person.breath()
}
}
doSomething(someone: mike as Person) // 멤버쉽 트레이닝을 갑니다 신남!
doSomething(someone: mike) // 멤버쉽 트레이닝을 갑니다 신남!
doSomething(someone: jenny) // 등교를 합니다
doSomething(someone: yagom) // 숨을 쉽니다
반응형
'프로그래밍 언어 > swift' 카테고리의 다른 글
[Swift] #8 오류처리 및 고차함수 (0) | 2021.01.22 |
---|---|
[Swift] #7 다양한 표현 및 확장 5 (assert / guard / 프로토콜 / 익스텐션) (0) | 2021.01.21 |
[Swift] #5 다양한 표현 및 확장 3 (상속 / 인스턴스 생성 / 소멸) (0) | 2021.01.20 |
[Swift] #4 다양한 표현 및 확장 2 (클로저/프로퍼티) (0) | 2021.01.20 |
[Swift] #3 다양한 표현 및 확장1 (구조체 / 클래스 / 열거형) (0) | 2021.01.20 |
Comments