Functions

The func keyword define new function.

Functions can be defined in a global scope, and local scope including within other functions.

/* simplified syntax
func <func-name>(<arg-name>:<arg-type>) -> <return-type>{

}
*/

func sum(a: Int, b: Int) -> Int {
    return a+b
}

passing arguments

A function can have a list of arguments in parentheses, separated by commas. Empty list is allowed.

Argument may have default value. In this case, you can omit that parameter when calling the function. Place parameters that don’t have default values at the beginning of a function’s parameter list.

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    // If you omit the second argument when calling this function, then
    // the value of parameterWithDefault is 12 inside the function body.
}

someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) 
// parameterWithDefault is 6

someFunction(parameterWithoutDefault: 4) 
// parameterWithDefault is 12

By default parameters are constants. The inout modifier allows pass parameter by reference, so function can change value of parameter. In this case you can not pass constants and literals.

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

argument's label

Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.

If a parameter has an argument label, the arguments must be labeled when you call the function.

func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)!  Glad you could visit from \(hometown)."
}

print(greet(person: "Bill", from: "Cupertino"))
// Prints "Hello Bill!  Glad you could visit from Cupertino."

If you don’t want an argument label for a parameter, write an underscore (_) instead of an explicit argument label for that parameter.

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
    // In the function body, firstParameterName and secondParameterName
    // refer to the argument values for the first and second parameters.
}
someFunction(1, secondParameterName: 2)

variable-length argument list

The ... specifies the variable number of arguments. In swift it is called variadic parameter.

A function can have multiple variadic parameters. The first parameter that comes after a variadic parameter must have an argument label.

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}

arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers

arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers

return value

You don’t need to specify a return type if no value will be returned.

The return statement finishes function execution and return specified value if necessary to caller.

You can return multiple values using tuple.

func printAndCount(string: String) -> Int {
    print(string)
    return string.count
}

func greet(person: String) {
    print("Hello, \(person)!")
}

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)
}

If the entire body of the function is a single expression, the function implicitly returns that expression.

func greeting(for person: String) -> String {
    "Hello, " + person + "!"
}

overloading

Swift supports overloading. This means, you can have several functions with same name but with different number of arguments or types of arguments in the same scope.

// same function name different arguments
func myFunc() { ... }
func myFunc(value: Int) -> Int{ ... }
func myFunc(value: String) -> String{ ... }
func myFunc(value1: Int, value2: Double) -> Double{ ... }