Search code examples
swiftfunctiontypesparameterssyntax

Function Types Example Code / Need Explanation / Swift


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?


Solution

  • 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.