Swift Functions

Functions are named, reusable blocks of code in Swift that can accept parameters, return values, and be shaped with expressive parameter labels.

Defining and calling a function

You define a function with the func keyword, followed by its name, a parameter list in parentheses, and an optional return type introduced with an arrow (->). Calling the function requires passing arguments that match the parameter list, and Swift enforces argument labels and types at compile time.

A simple function with a return value

func greeting(for name: String) -> String {
    return "Hello, \(name)!"
}

let message = greeting(for: "Ava")
print(message)

Parameter labels and argument labels

Swift functions distinguish between the external argument label used at the call site and the internal parameter name used inside the function body. By default a parameter's name serves as both, but you can specify a separate external label, or use an underscore to omit the label entirely, tailoring the function's call-site readability.

Custom argument labels

func move(from start: String, to destination: String) {
    print("Moving from \(start) to \(destination)")
}

func multiply(_ a: Int, by b: Int) -> Int {
    return a * b
}

move(from: "NYC", to: "LA")
print(multiply(6, by: 7))
Note: Well-chosen argument labels make call sites read like natural language, e.g. move(from: "NYC", to: "LA") is clearer than move("NYC", "LA").

Default values and variadic parameters

Parameters can have default values, letting callers omit an argument when the default is acceptable. A parameter can also be variadic, accepting zero or more values of the same type separated by commas, which the function receives as an array.

  • Default parameter values must come after all parameters without defaults, by convention.
  • A variadic parameter is written with three dots after its type, e.g. numbers: Int....
  • A function can have at most one variadic parameter.
  • Every function has an implicit type made up of its parameter types and return type, e.g. (Int, Int) -> Int.

Default and variadic parameters

func power(of base: Int, exponent: Int = 2) -> Int {
    var result = 1
    for _ in 0..<exponent { result *= base }
    return result
}

func total(of numbers: Int...) -> Int {
    return numbers.reduce(0, +)
}

print(power(of: 5))            // uses default exponent 2
print(power(of: 2, exponent: 10))
print(total(of: 1, 2, 3, 4, 5))
Note: Passing an in-out parameter requires an ampersand (&) at the call site, and the argument must be a variable, not a constant or literal.

Returning multiple values with tuples

A function's return type can be a tuple, allowing it to hand back several related values at once without defining a separate named type. Tuple members can be labeled for extra clarity when the caller destructures the result.

Returning a tuple

func minMax(of values: [Int]) -> (min: Int, max: Int)? {
    guard let first = values.first else { return nil }
    var currentMin = first
    var currentMax = first
    for value in values {
        if value < currentMin { currentMin = value }
        if value > currentMax { currentMax = value }
    }
    return (currentMin, currentMax)
}

if let result = minMax(of: [12, 4, 9, 30, 1]) {
    print("Min: \(result.min), Max: \(result.max)")
}

Function signature reference

FeatureSyntax exampleEffect
Default valueexponent: Int = 2Caller may omit the argument
Omit label_ a: IntNo label required at call site
Variadicnumbers: Int...Accepts a comma-separated list as an array
In-outcount: inout IntFunction can modify the caller's variable directly

Exercise: Swift Functions

In `func greet(to name: String)`, what is `to` used for?