I'm currently learning Swift function types and the book gives me such code to demonstrate how we can use variables with functions:
var manipulateInteger: (Int, Int) -> Int
func multNumber(_ first: Int, _ second: Int) -> Int {
return first * second
}
func addNumber(_ first: Int, _ second: Int) -> Int {
return first + second
}
manipulateInteger = multNumber
func doMath(_ manipulateInteger: (Int, Int) -> Int, _ a: Int, _ b: Int) {
print("The result is: \(manipulateInteger(a, b))")
}
doMath(addNumbers, 5, 10)
The commentary for last step sounds like this: "By calling this new function with the addNumber for the first parameter, we use the new function to sum the numbers and output the result."
I just want to understand if I'm getting it right: we changed manipulateInteger for addNumbers just to show that we can replace one function-parameter with another because they have the same function type? Or I'm missing something?
In your case, the variable manipulateInteger
, the functions multNumber
and addNumber
, and the parameter manipulateInteger
in the function doMath
are all entities of the same type (Int,Int) −> Int
.
You might have been confused by the fact that the closure variable var manipulateInteger
and the parameter manipulateInteger
in the function doMath
share the same name. In reality, they are not related, and the function parameter could have any name.
Inside the function, when referring to the parameter manipulateInteger
, you're using the value passed to that parameter when the function was called. This value could be any entity that matches the type (Int,Int) −> Int
.
Using identical property names can easily become confusing. This example should help clarify:
class Calculator {
var manipulateInteger: (Int, Int) -> Int
init(manipulateInteger: @escaping (Int, Int) -> Int) {
self.manipulateInteger = manipulateInteger
}
func doMath(_ manipulateInteger: (Int, Int) -> Int, _ a: Int, _ b: Int) {
let functionParamResult = manipulateInteger(a, b)
print("Result from the function parameter manipulateInteger: \(functionParamResult)")
let classPropertyResult = self.manipulateInteger(a, b)
print("Result from the class property manipulateInteger: \(classPropertyResult)")
}
}
func multNumber(_ first: Int, _ second: Int) -> Int {
return first * second
}
func addNumber(_ first: Int, _ second: Int) -> Int {
return first + second
}
let calculator = Calculator(manipulateInteger: multNumber)
calculator.doMath(addNumber, 3, 5)
Executing this code produces the following console output:
Result from the function parameter manipulateInteger: 8
Result from the class property manipulateInteger: 15
Thus, from within the function body, you can access both its parameter and the object's property, even if they have the same name.