Collections and functions

Swift Functions

Learn how to declare functions in Swift with the func keyword, pass labeled parameters, return values, and use tuples to return more than one value.

This tutorial belongs to the Swift series

Functions are how we organize code into named, reusable pieces.

You declare a function with the func keyword:

func bark() {
    print("woof!")
}

And you call it using its name, followed by parentheses:

bark() // prints "woof!"

When a function belongs to a structure, class, or enumeration, we call it a method. Same syntax, different home.

Returning a value

A function can return a value. You declare the return type after ->:

func bark() -> String {
    print("woof!")
    return "barked successfully"
}

And you can store the result:

let result = bark()
// result is "barked successfully"

If you declare a return type and forget the return, the compiler stops you with Missing return in instance method expected to return 'String'. Swift never lets a function silently return nothing when it promised a value.

Parameters

A function can accept parameters. Each one has a name and a type:

func bark(times: Int) {
    for _ in 0..<times {
        print("woof!")
    }
}

When you call the function, you write the parameter name as a label in front of the value:

bark(times: 3)

This prints woof! three times. You must pass every parameter the function declares, and you must use the labels.

Here’s a function with two parameters:

func bark(times: Int, repeatBark: Bool) {
    for _ in 0..<times {
        if repeatBark {
            print("woof woof!")
        } else {
            print("woof!")
        }
    }
}

You call it like this:

bark(times: 3, repeatBark: true)

When we talk about this function, we don’t call it bark(). We call it bark(times:repeatBark:). The labels are part of the name. That’s why Swift lets you define several functions called bark, as long as their parameters differ.

Dropping a label

Sometimes a label adds nothing. Put an underscore in front of the parameter name and callers skip it:

func bark(_ times: Int, repeatBark: Bool) {
    // ...the function body
}

Now you call it this way:

bark(3, repeatBark: true)

It’s common in Swift and iOS APIs to leave the first parameter unlabeled and label the rest. When you pick the names well, the call reads like a sentence.

Returning more than one value

A function can only return one value. When you need more, return a tuple:

func bark() -> (String, Int) {
    print("woof!")
    return ("barked successfully", 1)
}

And you decompose the result into separate constants:

let (result, num) = bark()

print(result) // "barked successfully"
print(num)    // 1

Nested functions

You can declare a function inside another function. The inner one is visible only inside the outer one, which is a nice way to keep a helper private to the code that uses it. I do this when a piece of logic is used twice in one function and nowhere else.

Lesson completed