Ah, thanks for the hint about nonmutating set
. I can confirm that:
@propertyWrapper struct MyWrapper {
var wrappedValue: Int {
get { 0 }
nonmutating set { }
}
}
struct MyStruct {
@MyWrapper var i: Int
}
print(type(of: \MyStruct.i)) // ReferenceWritableKeyPath<MyStruct, Int>
Removing just the nonmutating
keyword results in a WritableKeyPath
again.
I’m sure somebody put a whole lot of thought into this and there are good reasons why it is the way it is. Now I just need to figure out these reasons
Edit: What I’d come up with if put on the spot is: A struct property that can be set without mutating the struct itself must be something that “delegates” the mutation to some place behind a pointer, like the example by Rob Mayoff with the UnsafeMutablePointer
in this post. Another option would be a struct that delegates its storage to a singleton like UserDefaults
.
The crucial thing is that there must be a pointer involved somewhere, i.e. a reference to something else.
Therefore, key paths to properties of structs that have nonmutating setters are ReferenceWritableKeyPath
s.
I’m not sure this is convincing, but that’s what I’d guess.