Reputation: 1269
When I read the Swift documentation provided by Apple, I found some concept not clear for me...
When a closure’s type is already known, such as the callback for a delegate, you can omit the type of its parameters, its return type, or both. Single statement closures implicitly return the value of their only statement.
let mappedNumbers = numbers.map({ number in 3 * number })
print(mappedNumbers)
What does it means the callback for a delegate? Could you give me an example? If both are omitted, should we need the in
keyword?
Upvotes: 0
Views: 284
Reputation: 130132
There is nothing simpler. In this case the meaning of delegate
is that the closure is used as a variable. Consider the following example:
class Downloader {
var onDownloaded: ((Data) -> Void)?
func startDownloading() {
...
}
}
Used as:
let downloader = Downloader()
downloader.onDownloaded = { data in
print("Downloaded: \(data.count) B")
}
downloader.startDownloading()
As you can see, I did not specify neither the type or the return value in the closure, because the left side of the expression (.onDownloaded =
) provides them.
The same applies for method parameters:
func startDownloading(onDownloaded: ((Data) -> Void)?) {
...
}
However, we still need in
in the closure. The keyword separates the parameter names from the closure body. Of course, we could make the parameters anonymous:
downloader.onDownloaded = {
print("Downloaded: \($0.count) B")
}
Upvotes: 1
Reputation: 360
It states that the parameter type can be inferred from the delegate. A delegate is a protocol, which is where you define the types of the method parameters. This means that when implementing the delegate method, the compiler already knows about the method types through the declared protocol.
An example:
let sortedAnimals = animals.sort { (one: String, two: String) -> Bool in
return one < two
}
The first simplification is related to the parameters. The type inference system can calculate the type of the parameters in the closure:
let sortedAnimals = animals.sort { (one, two) -> Bool in return one < two }
The return type can also be inferred:
let sortedAnimals = animals.sort { (one, two) in return one < two }
The $i notation can substitute the parameter names:
let sortedAnimals = animals.sort { return $0 < $1 }
In single statement closures, the return keyword can be omitted:
let sortedAnimals = animals.sort { $0 < $1 }
For strings, there's a comparison function which makes string comparison even shorter:
let sortedAnimals = animals.sort(<)
Each step outputs the same result and it is for you to decide what is concise, but readable at the same time.
Upvotes: 1