이 글은 SE-0252 Key Path Member Lookup 제안을 통해 Swift 5.1에서 확장된 동적 멤버 찾아보기(dynamic member lookup) 기능을 간략히 살펴보는 글입니다.
이 업데이트는 Swift 4.2에서 추가된 @dynamicMemberLookup
의 기능을 좀 더 확장시킵니다. 일단 다짜고짜 기존(?) 예제부터 봅시다.
@dynamicMemberLookup
struct SomeInfo {
let properties: [String : String] = [
"name": "James",
"city": "LA"
]
subscript(dynamicMember string: String) -> String {
return properties[string]!
}
}
let info = SomeInfo()
info.name // "James"
info.city // "LA"
첫 줄의 @dynamicMemberLookup
이 이번 글의 핵심 키워드입니다. 그리고 이를 구현하는 부분이 subscript
부분입니다. subscript(dynamicMember:)
를 통해 사전형 프로퍼티에 액세스를 하고 있는데 문자열이 아니라 마치 일반 프로퍼티처럼 액세스 할 수 있게 만들어 주는 것이 바로 이 Dynamic Memeber Lookup의 기능입니다.
다만 이 예제는 5.1 업데이트 내용을 설명하기에는 좀 부족함이 있습니다.
5.1에서 확장된 기능에 맞게 다른 예제를 살펴봅시다.
@dynamicMemberLookup
struct Humanlike<T> {
private let primate: T
init(_ p: T) {
primate = p
}
subscript<U>(dynamicMember keyPath: WritableKeyPath<T, U>) -> U {
return primate[keyPath: keyPath]
}
}
이름은 인류(Humanlike)라는 거창한 이름인데 subscript를 빼면 별로 하는 일이 없는 코드네요. 근데 subscript 부분에 KeyPath를 사용하고 있다는 점이 좀 달라 보입니다. 어쨌든 이 구조체는 아마도 단독으로 사용하기 위한 용도는 아닐 거라고 생각되실 겁니다. 이제 다른 인스턴스를 넣어서 테스트해 봅시다.
struct HomoSapiens {
var name: String = "James"
var age: Int = 38
}
let a = Humanlike(HomoSapiens())
a.name // "James"
a.age // 38
호모사피엔스(HomoSapiens) 구조체를 하나 선언하고 인스턴스를 생성한 후 이를 Humanlike 구조체를 통해 액세스 하는 예제입니다. 여기서 Humanlike 구조체는 마치 자신의 프로퍼티인 것처럼 HomoSapiens 타입 인스턴스의 프로퍼티인 name
과 age
에 액세스 할 수 있게 해주고 있습니다.
하나 더 시험해 볼까요?
struct Ramapithecus {
var age: Int = 2
var skinRate: Float = 0.2
}
let b = Humanlike(Ramapithecus())
b.age // 2
b.skinRate // 0.2
b.name // error: value of type 'Ramapithecus' has no member 'name'
라마피테쿠스(Ramapithecus) 구조체를 하나 더 만들고 역시 이것의 인스턴스를 Humanlike를 통해 액세스 하는 예제입니다. 다만 이번에는 Ramapithecus에는 없는 프로퍼티를 액세스 하려 하였고 당연하게도 에러가 나고 있는 모습을 볼 수 있습니다. 그리고 그 에러 또한 아주 명백하게 Ramapithecus 인스턴스를 액세스 하려다 에러가 난 것처럼 보이기도 하네요.
대충 이런 식으로 쓰려고 만들어진 것이 이 @dynamicMemberLookup
입니다. 앞의 예제에서 봤다시피 이번 5.1에서는 문자열 기반에서 탈피하여 키 패스(Key Path)를 활용해서 사용할 수 있게 되어서 좀 더 쓸모 있게 변화 되었다는 것이 핵심입니다.
'기술적인 이야기 > 애플 플랫폼 개발' 카테고리의 다른 글
[Swift 5.1] 리턴 생략 가능 (SE-0255) (0) | 2019.11.05 |
---|---|
[Swift 5.1] Static Subscript (SE-0254) (0) | 2019.10.31 |
[Swift 5.1] 초기화 없는 배열 생성하기 (SE-0245) (0) | 2019.10.24 |
[Swift 5.1] Opaque Result Types 그리고 some (SE-0244) (0) | 2019.10.18 |
[Swift 5.1] 구조체 생성자에 기본값 지원 (SE-0242) (0) | 2019.10.17 |
댓글