Новое в Swift 5.1, вы можете использовать динамический поиск членов с ключевым путем.Это прекрасно работает для такого рода ситуации, когда ключевые пути поддерживают полную проверку типов.Вот упрощенный пример (без попытки отразить вашу реальную ситуацию):
struct Dog {
let name : String
}
@dynamicMemberLookup
struct Kennel {
let dog : Dog
subscript(dynamicMember kp:KeyPath<Dog,String>) -> String {
self.dog[keyPath:kp]
}
}
В результате получается, что с учетом питомника k
мы можем получить k.name
как способ получения k.dog.name
.
Но говорить k.xxx
было бы незаконно, потому что у Собаки нет свойства String xxx
;это то, что я имею в виду, когда говорю, что поддерживается полная проверка типов.
Старый способ - использовать протоколы.Таким образом, вы можете использовать расширение протокола для ввода шаблона.
protocol HasNameAndId {
var id: Int {get}
var name: String {get}
}
protocol WrapperOfHasNameAndId {
associatedtype T : HasNameAndId
var bar: T {get}
}
extension WrapperOfHasNameAndId { // boilerplate
var id: Int {
return self.bar.id
}
var name: String {
return self.bar.name
}
}
// ==============
struct Bar: HasNameAndId {
let id: Int
let name: String
}
class Foo : WrapperOfHasNameAndId {
let bar: Bar
init(bar: Bar) {
self.bar = bar
}
}
// =======
let f = Foo(bar: Bar(id: 1, name: "howdy"))
print(f.id) // 1
print(f.name) // "howdy"