What you want is some way to guarantee value semantics when writing generic code.
It’s a known hole, and admittedly quite a big one. I hope that there will be time for core language improvements like this in Swift 5. Be sure to raise the issue again once planning for that starts! - Karl > On 23. Jun 2017, at 23:43, Robert Bennett via swift-evolution > <[email protected]> wrote: > > Hello Swift Evolution, > > I’m bumping into an annoying problem with protocols. In a class or struct it > is common to have a `let` instance variable and assign it in `init`. > Unfortunately there is no way to translate this into a protocol with init in > an extension. If attempting to set the variable in init in an extension, it > must be of type { get set }, which means it cannot be a `let` constant in the > conforming type. AFAIK there is no way around this — if you want to set an > instance variable in an initializer in a protocol extension, it must be > marked as { get set }. The alternative is to write the initializer separately > for each adopting type, but this violates DRY. > > Hence, I am proposing a third option to go along with `get` and `set` in a > protocol. This would indicate that the variable can be a constant, but is > settable in an initializer. In this case, the conforming type *must* use > `let` to declare the variable. > > Option 1: the keyword `let`. If present, it would need to be the only thing > in the curly brackets because it simultaneously implies `get` and not `set`. > > protocol P { > var x: Int { let } > init(_ x: Int) > func modifyX() > } > extension P { > init(_ x: Int) { > self.x = x // This is ok; would not be ok if x were marked { get } > } > > func modifyX() { > self.x += 1 // Not allowed > } > } > > struct S: P { > let x: Int // This is ok; would not be ok if x were marked { get set } > } > > Option 2: `set(init)`. Can (and often will) coexist with `get`. > > protocol P { > var x: Int { get set(init) } > init(_ x: Int) > func modifyX() > } > extension P { > init(_ x: Int) { > self.x = x // This is ok; would not be ok if x were marked { get } > } > > func modifyX() { > self.x += 1 // Not allowed > } > } > > struct S: P { > let x: Int // This is ok; would not be ok if x were marked { get set } > } > > > I’d like to hear all of your thoughts on this. > > Best, > Robert > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
