I can imagine a setter being mutating for structs, but this does not apply to reference types since you're not modifying the reference but something inside the instance. Is this a bug in the compiler's parsing of the keyPath
access?
Mind providing a small example how to reproduce the issue you're facing?
Hello @DevAndArtist, it's been a while since I saw your name!
func setValue<Value>(_ value: Value, forKey path: WritableKeyPath<MyClassType, Value>) {
self[keyPath: path] = value
}
The above doesn't compile because self
is not mutable.
func setValue<Value>(_ value: Value, forKey path: WritableKeyPath<MyClassType, Value>) {
var me = self
me[keyPath: path] = value
}
This doesn't make sense to me, since MyClassType is a class, so mutating access shouldn't be required here.
Yeah, I'm not part of the server slack workspace anymore, but constantly active in the forums.
I think you're hitting the same issue as I recently did. Have you tried ReferenceWritableKeyPath
instead of WritableKeyPath
since you're operating on a reference type?!
A WritableKeyPath
is a key path that modifies its root value in-place. Even on a class type, a WritableKeyPath
could rebind the reference, which would require that the variable containing the reference be mutable. For instance, if we added the identity key path, it would be a WritableKeyPath
, and you wouldn't want to be able to allow changing an immutable class reference through it:
let x = NSObject()
x[keyPath: \.self] = NSObject() // \.self is a WritableKeyPath, but `x` can't be rebound
A ReferenceWritableKeyPath
modifies state through a reference, such as a class reference, and does not modify that reference, which is what you want when talking about mutable class properties.