Given:
struct Foo {
let bar: Int
}
In an init method, you can do:
init() {
self.bar = 42
}
However, unfortunately, you cannot do:
init() {
self[keyPath: \.bar] = 42
}
This error is thrown: "'self' used before all stored properties are initialized."
This seems like a compiler bug, or at least, a counter-intuitive aspect of keypaths. If a property setter works on self
before its properties are initialized, then a keyPath subscript should also work.
So I would like to pitch the idea of updating keypaths so they can be used to init properties, perhaps using a new type of keypath if that seems best.
I feel like this would greatly enhance the power of KeyPaths for purposes of dependency injection.
We may need to require that any init which relies on passed-in keypaths must be a failable init, and/or provide a convenience check to determine whether some set of keypaths is sufficient to initialize an instance of a given type.
One approach could be to conditionally cast passed-in keypaths as? WritableKeyPath
within the init method; if a variable has no value yet then it would be writable at that point in time, and within the init method's scope.
Another approach might be to cast to a new InitializableKeyPath type.
I'm sure the geniuses here can think of something better, or more likely, explain why this is a horrible idea, but at any rate I wanted to open this up for discussion. It's an idea stemming from a prior pitch I made, but I realized this feature would be needed first in any event, so would like to know whether it's feasible or desirable.
(Apologies if it's been pitched before, I did a search but did not come up with an exact match. I think this could work nicely though with some of the other keypath-related proposals, though!)