Function definition and call

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}
print(greet(person: "Anna")) / / print"Hello, Anna!"
print(greet(person: "Brian")) / / print"Hello, Brian!"
Copy the code

Multiparameter function

func greet(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return greetAgain(person: person)
    } else {
        return greet(person: person)
    }
}
print(greet(person: "Tim", alreadyGreeted: true)) / / print"Hello again, Tim!"
Copy the code

No return value function

func greet(person: String) {
    print("Hello, \(person)!")
}
greet(person: "Dave"/ / print"Hello, Dave!"
Copy the code

Note that strictly speaking, the greet(person:) function returns a value even though no return value is defined. Functions that do not define a return type return a special Void value. It is an empty tuple with no elements and can be written as ().

Multiple return value functions

You can use tuples to return multiple values as a compound value from a function.

In this example, we define a function called minMax(array:) to find the minimum and maximum values in an array of type Int.

func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
Copy the code

Optional tuple return type

If the tuple type returned by a function has the possibility that the entire tuple has “no value”, you can use the optional tuple return type to reflect the fact that the entire tuple can be nil. You can define an optional tuple by placing a question mark after the closing parenthesis of the tuple type, for example (Int, Int)? Or (String, Int, Boolean)?

Note optional tuple types such as (Int, Int)? And tuples contain optional types such as (Int? , Int?) Optional tuple type, the entire tuple is optional, not just the value of each element in the tuple.

The previous minMax(array:) function returns a tuple of two ints. However, the function does not perform any security checks on the array passed in. If the array argument is an empty array, minMax(array:) defined above will raise a runtime error when attempting to access array[0].

To safely handle this “empty array” problem, rewrite the minMax(array:) function to use an optional tuple return type and return nil if the array is empty:

func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.isEmpty { return nil }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}
Copy the code

Ignore parameter labels

If you don’t want to add a label to an argument, use an underscore (_) instead of an explicit argument label.

func someFunction(_ firstParameterName: Int, secondParameterName: } someFunction(1, secondParameterName: 2) {firstParameterName: secondParameterName;Copy the code

Default Parameter Value

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {// parameterWithDefault is passed in to the function body with a value of 12 if you don't pass the second argument when you call it. } someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault = 6 someFunction(parameterWithoutDefault: 4) // parameterWithDefault = 12Copy the code

Function types as parameter types

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")}printMathResult(addTwoInts, 3, 5) // Print"Result: 8"
Copy the code

This example defines the printMathResult(::_:) function, which takes three arguments: the first argument is called mathFunction and is of type (Int, Int) -> Int. You can pass in any function of that type; The second and third arguments, called a and b, are of type Int and serve as input values to the given function.

When printMathResult(::_:) is called, it is passed into the addTwoInts function and the integers 3 and 5. It calls addTwoInts with incoming 3 and 5 and prints the result: 8.

The printMathResult(:::) function simply prints the result of a call to another mathematical function of the appropriate type. It does not care how the passed function is implemented, only whether the passed function is of the correct type. This allows printMathResult(:::) to transfer some functionality to the caller implementation in a type-safe manner.

Function type as return type

func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}
var currentValue = 3
letMoveNearerToZero = chooseStepFunction(Backward: currentValue > 0) // moveNearerToZero now points to the stepBackward() function.print("Counting to zero:")
// Counting to zero:
whilecurrentValue ! = 0 {print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!"/ / 3... / / 2... / / 1... // zero!Copy the code

Nested function

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
whilecurrentValue ! = 0 {print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!") / / - 4... / / - 3... / / - 2... / / - 1... // zero!Copy the code