Kindred
Kindred

Reputation: 1269

Swift closure omission example?

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

Answers (2)

Sulthan
Sulthan

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

bajocode
bajocode

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

Related Questions