Hi Dimitri, You may be interested in taking a look at a proposal I introduced about a year ago which was deferred. Memberwise initialization is a topic we intend to revisit eventually. This may happen in phase 2 of the Swift 4 effort, or may not happen until Swift 5.
https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md Matthew > On Feb 15, 2017, at 9:38 AM, Dimitri Racordon via swift-evolution > <[email protected]> wrote: > > Hello community! > > While writing a Swift introduction tutorial for students, I’ve been stumbling > upon the rules for struct default and memberwise initializers. > I failed to find explanations in Apple’s language guide, but as far as I > could observe, I think the rules don’t fit interesting use-cases. > > Here are the cases that I was able to identify (I hope you don’t mind > millennials and their obligatory Pokemon references): > > First, as documented in Apple’s guide, structs that doesn’t define any > initializer and have no default values receive a memberwise initializer: > > typealias Species = (number: Int, name: String) > > struct Pokemon { > let species: Species > var level: Int > var nickname: String > } > > let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby") > > Structs that define a default value for all their properties receive a > default initializer: > > struct Pokemon { > let species: Species = (001, "Bulbasaur") > var level: Int = 1 > var nickname: String = "bulby" > } > > let bulby = Pokemon() > > Now digging a bit deeper, I noticed that they also seem to receive an > initializer for their non-constant properties: > > let bulby = Pokemon(level: 1, nickname: "bulby") > > If no value is provided for one (or several) of its variable properties, they > receives an initializer for all their variable properties: > > struct Pokemon { > let species: Species = (001, "Bulbasaur") > var level: Int = 1 > var nickname: String > } > > let bulby = Pokemon(level: 1, nickname: "bulby") > > Finally, if they're given a default value for their variable properties but > not for their constant properties, they receive the full memberwise > initializer only: > > struct Pokemon { > let species: Species > var level: Int = 1 > var nickname: String = "bulby" > } > > let bulby = Pokemon(species: (001, "Bulbasaur"), level: 1, nickname: "bulby") > > If the two extreme cases sounds perfectly valid to me (no default value vs > all default values), the mixed situations do not. > In particular, it seems strange that a struct without a default value for its > constant property, but one for all its variable properties receives the > memberwise initializer only. I guess that would be a common “mixed situation” > case, yet the provided initializer is actually useless. > > Receiving the full memberwise initializer is fine, but I would also expect to > receive some kind of "partial memberwise” initializer for all properties > (constants or variables) that are not defined: > > struct Pokemon { > let species: Species > var level: Int = 1 > var nickname: String = "bulby" > } > > let bulby = Pokemon(species: (001, "Bulbasaur”)) > print(bulby) > // Prints "Pokemon(species: (1, "Bulbasaur"), level: 1, nickname: "bulby")" > > Besides, that would avoid some tedious initializer definitions. Indeed, If I > want to get the desired result, I have to write this kind of initializer: > > struct Pokemon { > let species: Species > var level: Int = 1 > var nickname: String = "bulby" > > init(species: Species, level: Int? = nil, nickname: String? = nil) { > self.species = species > > if level != nil { > self.level = level! > } > > if nickname != nil { > self.nickname = nickname! > } > } > } > > In addition to be rather wordy, it arguably destroys the purpose of defining > a default value for variable properties in the first place, since imho this > approach is clearer (unless maybe for some more complicated structs with > multiple layers of initializer delegation): > > struct Pokemon { > let species: Species > var level: Int > var nickname: String > > init(species: Species, level: Int = 1, nickname: String = "bulby") { > self.species = species > self.level = level > self.nickname = nickname > } > } > > Thanks. > > Dimitri Racordon > > _______________________________________________ > 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
