I have an array of CLPlacemark. I'm following and example and I don't understand why the second code is correct.
Example 1: This code is correct.
let placemarks: [CLPlacemark]
....
placemarks
.compactMap({ placemark in
Location(placemark: placemark)
})
...
Example 2: This code is also correct.
let placemarks: [CLPlacemark]
....
placemarks
.compactMap(Location.init(placemark:))
...
Do you know why I can create Locations without passing the parameter?
Initialisers can be thought of as a regular function that returns a value of whatever type the initialiser is initialising. They have a type when you explicitly write out init
.
In the same way that you can write:
func makeLocation(placemark: CLPlacemark) -> Location? { ... }
// I'm not *calling* `makeLocation` here - I'm just assigning the function itself to f
let f: (CLPlacemark) -> Location? = makeLocation(placemark:) // or just makeLocation
You can also write:
struct Location {
init?(placemark: CLPlacemark) { ... }
}
let f: (CLPlacemark) -> Location? = Location.init(placemark:) // or just Location.init
See also this section of the Swift Guide if this is the first time you have seen a function itself being used as a value, instead of being invoked.
It works the same way in compactMap
. compactMap
expects a function of type (T) -> U?
where T
and U
are type parameters.
You could pass the lambda { placemark in Location(placemark: placemark) }
. This lambda would be of type (CLPlacemark) -> Location?
. But the type of Location.init
is also (CLPlacemark) -> Location?
matches this pattern, so you are able to pass it to compactMap
too.