I\'m reading \"The swift programming language 4.2\". In the beginning chapter, page 23, I have this following requirement:
Rewrite the closure to return z
Rather than annotating the parameter type you have to specify the return type of the closure
let myArray = [1, 2, 3, 4, 5] // You don't even need to annotate the array, the compiler knows the type.
let result = myArray.map({ number -> Int in
if number % 2 != 0 {
return 0
} else {
return number
}
})
Or with trailing closure syntax and shorthand argument names. In this case the compiler can infer everything
let result = myArray.map { $0 % 2 != 0 ? 0 : $0 }
Make it less ambiguous by specifying the return type with as [Int]
:
myArray.map({ (number: Int) in
if number % 2 != 0 {
return 0
} else {
return number
}
}) as [Int]
Or :
let result: [Int] = myArray.map({ (number: Int) in
if number % 2 != 0 {
return 0
} else {
return number
}
})
print(result) //[0, 2, 0, 4, 0]
As noted by vadian: The ambiguity comes from the fact that the generic return type in the closure cannot be inferred.
To understand how the compiler infers the return type of a closure, let's go back to the syntax of a closure :
let myClosure: returnType = { (params) -> returnType in
statements
}
Here, the type of myClosure
is returnType
. And it's set in two places: after :
, and after ->
. You could use type inference by removing the returnType
from one of the two places, but not both.
So you could remove it from inside the curly braces (like in the code above) :
let result: [Int] = myArray.map({ (number: Int) in
Or just after the variable name, and specifying the return type of the closure inside the the curly braces:
let result = myArray.map({ (number: Int) -> Int in