Apple's book "The Swift Programming Language (Swift 3.1)" states the following:
As with function and method parameters, initialization parameters can have both a parameter name for use within the initializer’s body and an argument label for use when calling the initializer.
However, initializers do not have an identifying function name before their parentheses in the way that functions and methods do. Therefore, the names and types of an initializer’s parameters play a particularly important role in identifying which initializer should be called. Because of this, Swift provides an automatic argument label for every parameter in an initializer if you don’t provide one.
I don't understand the last sentence, as I didn't notice any difference between functions/methods and initializers when it comes to parameters names/labels. How is the argument label automatically provided for an initializer?
The feature being described is this: Given a struct:
struct Point {
let x: Double
let y: Double
}
Swift will automatically generate Point.init(x: Double, y: Double)
. If you add an init
method of your own in the main struct
definition, then Swift won't create that automatic init
. (If you add an init
in an extension, then you will get an automatic init
. This is why people often add convenience init
in an extension for structs.)
The point the last paragraph is trying to make is that Point(x:y:)
is preferable to Point(_:_:)
. The labels in an initializer are even more valuable than labels in method names, because all initializers have the same "base" name ("init"). They're just explaining why they didn't choose a more implicit default that some people might expect coming from other languages.
In short, sometimes unlabeled parameters make sense in methods depending on what the name of the method is and how unambiguous that makes the first parameter. But in init
, unlabeled parameters should be eyed with strong suspicion.