The Problem
Let's say I'm writing a module that will be imported somewhere else, and a struct that I define in my module needs to be initializable outside of my module. I am forced to write out the memberwise initializer for my struct by hand, because only then can I mark it public
- the one that is synthesized for me will have internal
access if my struct is public
, meaning that the initializer won't be accessible from outside my module. This memberwise initializer that I have to write out and maintain is arbitrarily large because my struct can contain an arbitrary number of properties. I think this is referred to as a behavior cliff or something like that - a theoretically incremental increase in my needs causes a sudden large increase in my boilerplate, introducing room for errors aside from being a drag.
My Proposed Solution (or I'd love to hear why it's a terrible idea)
What if I could resolve this situation by writing:
public struct MyStruct {
public var foo: String
public var bar: Bool?
public var baz: Array<Int>
public memberwise init
}
Introducing the memberwise
keyword, only to be applied before an init declaration with no parameters and no body, would allow us to customize various aspects of the canonical synthesized initializer for a given struct without having to write out the obvious part. This would allow us to do things like:
struct MyStruct <T> {
public var foo: String
public var bar: Bool?
public var baz: Array<T>
public memberwise init where T: Codable
// For whatever reason we want to allow outsiders to create the struct only if the generic parameter is Codable
internal memberwise init
}
struct MyStruct <T> {
private var foo: String
private var bar: Bool?
private var baz: Array<T>
public memberwise init
// Here we get to allow outsiders to initialize the members but not read them thereafter.
}
Thoughts, reactions?