I'm trying to learn about swift and closures. I'm stuck on this example.
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
What is (number: Int) -> Int? Is it a function? Where is it defined? https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-ID1
What does the keyword "in" do? The docs say to use "to separate the arguments and return type from the body". I'm not sure I understand this. Why isn't "in" used to separate "let result = 3 * number" from "return result".
Closures can be seen as blocks of code that can be passed around in your code. Blocks of code are often referenced as lambdas in other programming languages. An example from UIKit if for Adding a closure as a target to UIButton and other controls in Swift: let button = UIButton(type: .
Closures can capture and store references to any constants and variables from the context in which they're defined. This is known as closing over those constants and variables. Swift handles all of the memory management of capturing for you. Don't worry if you aren't familiar with the concept of capturing.
There are two kinds of closures: An escaping closure is a closure that's called after the function it was passed to returns. In other words, it outlives the function it was passed to. A non-escaping closure is a closure that's called within the function it was passed into, i.e. before it returns.
Understanding closure syntax in Swift For closures, we must always write down the return type even when the closure doesn't return anything. Instead of -> Void or "returns Void ", this type specifies -> () or "returns empty tuple". In Swift, Void is a type alias for an empty tuple.
A closure is just a function with the parameters moved inside the brackets, with the keyword in
to separate the parameters from the function body. The two following examples define equivalent functions:
func myFunc(number: Int) -> Int {
let result = 3 * number
return result
}
let myClosure = { (number: Int) -> Int in
let result = 3 * number
return result
}
You can actually call them both in exactly the same way:
let x = myFunc(2) // x == 6
let y = myClosure(2) // y == 6
Notice how the second example is exactly the same as the first, only in the first example, the parameters (number: Int) -> Int
are outside the brackets, and in the second example the parameters are inside the brackets, followed by the keyword in
.
map
works by taking an array (numbers
, in your example) and creating a new array that is the result of applying the closure function to each element in numbers
. So if numbers
is [1, 2, 3]
, the example above will start with 1
. It will apply the closure function which will produce a 3
(cuz all it does is multiply the element from the first array by 3). It does that for each element in numbers
, until it has produced a new array, [3, 6, 9]
.
If you wanted to, you could call map
using the names of either the above function or the above closure, or by writing it out explicitly inside of map
. All of the below examples are totally equivalent:
let numbers = [1, 2, 3]
// Example 1
let times3 = numbers.map(myFunc) // times3 == [3, 6, 9]
// Example 2
let timesThree = numbers.map(myClosure) // timesThree == [3, 6, 9]
// Example 3
let xThree = numbers.map({ (number: Int) -> Int in
let result = 3 * number
return result // xThree == [3, 6, 9]
})
Note that Example 3 is the same as Example 2, only in Example 3 the closure is spelled out explicitly inside of map
, whereas in Example 2 the closure has been assigned to a constant called myClosure
, and the constant has been supplied to map
.
Hope this helps - closures are fun, but confusing.
The function you're calling takes a closure as its parameter:
numbers.map({...})
The closure provided to the function is expected to receive a parameter when it is executed by the function you called. This parameter is defined in your closure:
(number: Int) -> Int in
You may now use the parameter in the contents of the closure
let result = 3 * number
return result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With