Functions and argument labels

Swift · Essentials · 10 min

Argument labels shape how every Swift API reads, so you need them to use or design any API.

A function is declared with func name(parameters) -> ReturnType. Each parameter has an argument label (used at the call site) and a parameter name (used inside). By default they're the same; write func move(from start: Int, to end: Int) to use different ones, or _ to omit the label: func square(_ x: Int).

Labels make calls read like phrases: move(from: 1, to: 5). Follow the API Design Guidelines: name for clarity at the point of use.

Other features:

  • Default values: func greet(_ name: String, loud: Bool = false).
  • Variadic parameters: func sum(_ xs: Int...) receives an array.
  • inout parameters can be modified, called with &: swap(&a, &b).
  • Return several values with a tuple: -> (min: Int, max: Int).
  • A single-expression body can omit return.
  • Functions can be overloaded by parameter types and labels.

Parameters are constants inside the function. Use @discardableResult when ignoring a return value is normal; otherwise the compiler warns about unused results.

Functions are first-class: their type looks like (Int, Int) -> Int, and they can be stored, passed and returned.

Example

func clamp(_ value: Int, between low: Int = 0, and high: Int) -> Int {
    min(max(value, low), high)
}
print(clamp(15, and: 10))              // 10
print(clamp(-3, between: -1, and: 5))  // -1

func stats(_ xs: Int...) -> (min: Int, max: Int)? {
    guard let lo = xs.min(), let hi = xs.max() else { return nil }
    return (lo, hi)
}
if let s = stats(4, 9, 1) { print(s.min, s.max) }  // 1 9

func double(_ n: inout Int) { n *= 2 }
var x = 21
double(&x)
print(x)                               // 42

let op: (Int, Int) -> Int = (+)
print(op(2, 3))                        // 5

Remember

  • Argument label (outside) vs parameter name (inside); _ drops the label
  • Default values, variadics and inout with &
  • Return named tuples for multiple results

Watch out for

  • Overusing inout instead of returning a new value — it makes code harder to follow.

Check yourself

  1. Given `func move(from start: Int, to end: Int)`, how is it called?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.swift.org/swift-book/documentation/the-swift-programming-language/functions/