![Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath]](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
키 경로 KeyPath
객체의 값을 바로 꺼내오는 것이 아닌, Key
또는 KeyPath
를 이용해서 간접적으로 프로퍼티 위치 참조나 데이터를 가져오거나 수정하는 방법이다.
키 경로를 사용해 간접적으로 특정 타입의 어떤 프로퍼티 값을 가리켜야 할지 미리 지정해 두고 사용 가능. 여기서 경로는 프로퍼티 이름이라고 생각하면 된다.
키 경로는 역슬래시( \
) 와 타입, 마침표( .
) 경로로 구성
class Person { var name: String init(name: String) { self.name = name } } struct Stuff { var name: String var owner: Person } print(type(of: \Person.name)) //ReferenceWritableKeyPath<Person, String> print(type(of: \Stuff.name)) //WritableKeyPath<Stuff, String>
키 경로는 기존 키 경로에 하위 경로를 덧붙일 수도 있다.
let keyPath = \Stuff.owner let nameKeyPath = keyPath.appending(path: \.name)
또, 각 인스턴스 keyPath
서브 스크립트 메서드에 키 경로를 전달해 프로퍼티에 접근도 가능하다.
struct Address { var town: String } struct Person { var address: Address } let address = Address(town: "한옥마을") let Seogon = Person(address: address) let SeogonAddress = Seogon[keyPath: \.address] //Address(town: "한옥마을") let SeogonTown = Seogon[keyPath: \.address.town] //한옥마을
키 경로 만드는 법
![Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - 키 경로 만드는 법 Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - 키 경로 만드는 법](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
class Person { let name: String init(name: String) { self.name = name } } struct Stuff { var name: String var owner: Person } let seogun = Person(name: "서근") var iPhone = Stuff(name: "아이폰", owner: seogun) let referenceWritableKeyPath = \Stuff.name iPhone[keyPath: referenceWritableKeyPath] //아이폰
이런 식으로 키 경로를 만들어서 사용하고 싶은 곳에 사용 가능! 예를 들자면 아래와 같다
class Person { let name: String init(name: String) { self.name = name } } struct Stuff { var name: String var owner: Person } let seogun = Person(name: "서근") let cheolsu = Person(name: "철수") let iPhone = Stuff(name: "아이폰 12 mini", owner: seogun) var Macbook = Stuff(name: "맥북프로", owner: cheolsu) let airPod = Stuff(name: "에어팟 프로", owner: seogun) let stuffNameKeyPath = \Stuff.name let ownerKeyPath = \Stuff.owner // ownerKeyPath의 owner은 class Person을 참조하고 있기때문에 // \Stuff.owner.name 과 같은 표현 let ownerNameKeyPath = ownerKeyPath.appending(path: \.name) print(iPhone[keyPath: stuffNameKeyPath]) //아이폰 12 mini print(Macbook[keyPath: stuffNameKeyPath]) //맥북 프로 print(airPod[keyPath: stuffNameKeyPath]) //에어팟 프로 print(iPhone[keyPath: ownerNameKeyPath]) //서근 print(Macbook[keyPath: ownerNameKeyPath]) //철수 print(airPod[keyPath: ownerNameKeyPath]) //서근 //키 경로와 서브스크립트를 이용해 프로퍼티에 접근해 값을 변경할 수 있음 //Macbook은 변수로 선언 했기 때문에 가능 Macbook[keyPath: stuffNameKeyPath] = "맥북 M1" print(Macbook[keyPath: stuffNameKeyPath]) //맥북 M1 Macbook[keyPath: ownerKeyPath] = seogun print(Macbook[keyPath: ownerNameKeyPath]) //서근 //반대로 상수로 선언한 타입과 읽기 전용 프로퍼티는 값을 바꿔줄 수 없음 iPhone[keyPath: stuffNameKeyPath] = "아이폰 13 pro" //error : Cannot assign through subscript: 'iPhone' is a 'let' constant seogun[keyPath: \Person.name] = "라쿤" //error : 키 경로가 읽기 전용입니다.
KeyPath 종류
![Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류 Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류](https://blog.kakaocdn.net/dn/bdnbjl/btrp95WVr1B/nKKTNSZGBDa8oiTGnVkTc0/img.png)
WritableKeyPath
struct Person { var name: String } struct Stuff { var owner: Person } let writableKeypath = \Stuff.owner.name
person
의 name
이 변수 이기 때문에 변경 가능한 모든 프로퍼티에 대한 read & write access를 제공하기 때문에 writableKeyPath
가 된다. 만약 name
이 상수이면 수정이 불가(Read-only
) 하므로 WritableKeyPath
가 아닌 일반적인 KeyPath
타입이 된다.
![Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류 - WritableKeyPath Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류 - WritableKeyPath](https://blog.kakaocdn.net/dn/GKh4z/btrp7RdON17/TnCIxLeKNYu2fNm3PkvZp0/img.png)
ReferenceWritableKeyPath
class Person { var name: String init(name: String) { self.name = name } } class Stuff { var name: String var owner: Person init(name: String, owner: Person) { self.name = name self.owner = owner } } let seogun = Person(name: "서근") var iPhone = Stuff(name: "아이폰", owner: seogun) let referenceWritableKeyPath = \Stuff.name iPhone[keyPath: referenceWritableKeyPath] //아이폰
위에서 사용한 코드는 class
를 사용하고 있기 때문에 자동으로 ReferenceWritableKeyPath
타입이 됨.
![Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류 - ReferenceWritableKeyPath Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] - 키 경로 KeyPath - KeyPath 종류 - ReferenceWritableKeyPath](https://blog.kakaocdn.net/dn/UqGW5/btrqijfyNrN/gNkAmYU6gD4IqEOHkm28s1/img.png)
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [메서드 #2 mutating] (0) | 2022.01.14 |
---|---|
Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] (0) | 2022.01.13 |
Swift : 기초문법 [프로퍼티#4 - 타입 프로퍼티] (0) | 2022.01.10 |
Swift : 기초문법 [프로퍼티#3 - 프로퍼티 옵저버(감시자) - didSet, willSet] (0) | 2022.01.09 |
Swift : 기초문법 [프로퍼티#2 - 연산 프로퍼티] (0) | 2022.01.08 |