5:12 AM
Joe Groff added a comment - 7 Sep 2017 2:49 AM This is by design. You can't write back through optional chains, since there's nowhere to write to if the element is nil.
5:12 AM
😭
5:14 AM
あー、確かに non-nil しか書き戻せないというのを記述不能なのか。
5:15 AM
Jaden Geller and Matthew Johnson suggested some extensions to Optional that could make working with writable key paths more expressive within the current model:
extension Optional { // Produce the `default` value if `self` is nil. subscript(default value: Wrapped) -> Wrapped { get { return self ?? value } set { self = newValue } } // Act like optional chaining on read, while allowing "writes" that drop // the value on the floor if `self` is nil. subscript<T>(droppingWritesOnNil path: WritableKeyPath<Wrapped, T>) -> T? { get { return self?[keyPath: path] } set { if let newValue = newValue { self?[keyPath: path] = newValue } } } }
5:19 AM
↑使ったらネストした KeyPath で記述できました。 @swiftbot extension Optional { // Produce the `default` value if `self` is nil. subscript(default value: Wrapped) -> Wrapped { get { return self ?? value } set { self = newValue } } // Act like optional chaining on read, while allowing "writes" that drop // the value on the floor if `self` is nil. subscript<T>(droppingWritesOnNil path: WritableKeyPath<Wrapped, T>) -> T? { get { return self?[keyPath: path] } set { if let newValue = newValue { self?[keyPath: path] = newValue } } } } struct Foo { var a: Int = 42 } struct Bar { var foo: Foo? = Foo() } var bar = Bar() bar[keyPath: \Bar.foo[droppingWritesOnNil: \.a]] = -1 print(bar.foo!.a) bar.foo = nil bar[keyPath: \Bar.foo[droppingWritesOnNil: \.a]] = 999 print(String(describing: bar.foo)) (edited)
🛠 1