Я люблю всякие фичи, полезные и не очень, даже заглядываю в другие языки (современные GO/Rust/Kotlin) посмотреть что там и как, естественно слежу за свифтом, одна из таких будущих фич (уже в мастере ждем в 5.1) показалась мне особенно интересной.
Предложение SE-0252 позволяет искать свойства с помощью KeyPath. При доступе к свойству (через точку) будет вызван subscript который принимает KeyPath, KeyPath типизирован а это autocomplete и проверка компилятором как у обычных свойств.
Можно придумать кучу различных фич, например пример автора с линзами:
struct Point {
let x: Int
var y: Int
}
@dynamicMemberLookup
struct Lens<T> {
var obj: T
init(_ obj: T) {
self.obj = obj
}
subscript<U>(dynamicMember member: KeyPath<T, U>) -> Lens<U> {
get { return Lens<U>(obj[keyPath: member]) }
}
subscript<U>(dynamicMember member: WritableKeyPath<T, U>) -> Lens<U> {
get { return Lens<U>(obj[keyPath: member]) }
set { obj[keyPath: member] = newValue.obj }
}
}
var lens = Lens(Point(x: 0, y: 0))
_ = lens.x // converted into `lens[dynamicMember: KeyPath<Point, Int>`
_ = lens.y = Lens(10) // converted into `lens[dynamicMember: WritableKeyPath<Point, Int>]`
Или можно встраивать структуры в структуры:
@dynamicMemberLookup
protocol DelegateWrapper {
associatedtype Delegate
var deleagete: Delegate { get }
}
extension DelegateWrapper {
subscript<U>(dynamicMember member: KeyPath<Delegate, U>) -> U {
get { return deleagete[keyPath: member] }
}
}
struct ArrayManager {
let addString: (String) -> Void
let removeString: () -> Void
let getArray: () -> [String]
init() {
var array = [String]()
addString = { array.append($0) }
removeString = { array.removeLast() }
getArray = { return array }
}
}
struct Controller: DelegateWrapper {
let deleagete = ArrayManager()
init() {
self.addString("A")
self.addString("B")
self.removeString()
self.addString("C")
print(self.getArray())
}
}
_ = Controller()
В голову ещё приходит прокси, но я пока не придумал как
Тулчейн можно скачать здесь.