Every now and then, I take some time out of my day to explore something about the Swift language that I don't know yet. There is a lot left to explore. I document my findings in a series I named What The Swift. If you are curious about the more subtle details of the Swift language, then this series is for you.

In the previous episodes of this series, we explored AnyObject and Any. Another keyword you encounter frequently in Swift is Void. What is Void? That is the focus of this installment of What The Swift.

Get Ready to Play

Open Xcode and and create a new playground. Choose the Blank template from the iOS section. Name the playground What The Swift, tell Xcode where you'd like to save the playground, and click Create.

What Is Void in Swift

Exploring the Swift Standard Library

Remove the contents of the playground and add an import statement for Foundation.

import Foundation

Let's start by defining a function, sayHello(), that accepts no arguments and returns nothing. This should look familiar.

import Foundation

func sayHello() {

}

The function declaration indicates that it returns nothing, but that isn't true. A function that doesn't specify a return type returns Void. This means we can update the function declaration like this.

import Foundation

func sayHello() -> Void {

}

The functionality of the sayHello() function hasn't changed. That is important to understand. What changed is that we explicitly indicate that the return type of sayHello() is Void. This brings us to the question of this episode. What does Void mean in Swift?

What Is Void in Swift?

Plenty of languages define Void. The question is how Swift defines Void. Press Command and click Void in the function declaration. This takes you to the definition of Void in the Standard Library. The answer is pretty clear. Take a moment to let this sink in.

/// The return type of functions that don't explicitly specify a return type,
/// that is, an empty tuple `()`.
///
/// When declaring a function or method, you don't need to specify a return
/// type if no value will be returned. However, the type of a function,
/// method, or closure always includes a return type, which is `Void` if
/// otherwise unspecified.
///
/// Use `Void` or an empty tuple as the return type when declaring a closure,
/// function, or method that doesn't return a value.
///
///     // No return type declared:
///     func logMessage(_ s: String) {
///         print("Message: \(s)")
///     }
///
///     let logger: (String) -> Void = logMessage
///     logger("This is a void function")
///     // Prints "Message: This is a void function"
public typealias Void = ()

As the documentation explains, Void is a type alias for (), an empty tuple. This means we can replace Void with an empty tuple in the function declaration of sayHello().

import Foundation

func sayHello() -> () {

}

There are a few details I want to highlight. First, a function, method, or closure always returns something. Second, if a function, method, or closure returns nothing, it actually means that it returns an empty tuple. In other words, a function, method, or closure always returns a tuple, but it is possible that the tuple is empty.

When Should You Use Void?

The documentation states that a function that doesn't specify a return type returns an empty tuple. You may be wondering why you would ever use Void. The documentation provides the answer. You use Void to declare the type of a function, method, or closure. Take a look at this example.

internal final class SessionManager {

    // MARK: - Properties

    var didSignOut: (() -> Void)?

    // MARK: - Helper Methods

    private func destroySession() {
        didSignOut?()
    }

}

We declare a class with name SessionManager. The SessionManager class declares a property with name didSignOut. The didSignOut property has an optional function type. The function accepts no arguments and returns Void. We cannot omit Void in this example. If we remove Void, then the compiler no longer understands the meaning of the property declaration. The compiler is smart, but it doesn't have enough information to infer what the type of the didSignOut property is.

Void and Function Types

By removing Void from the property declaration, we rendered the contents of the playground invalid Swift. There is one change we can make, though. Because Void is a type alias for an empty tuple, we can replace Void with an empty tuple. The compiler is fine with that.

internal final class SessionManager {

    // MARK: - Properties

    var didSignOut: (() -> ())?

    // MARK: - Helper Methods

    private func destroySession() {
        didSignOut?()
    }

}

Notice that we have a pair of parentheses, a return arrow, and another pair of parentheses. It is important to understand that the second pair of parentheses is an empty tuple, but the first pair of parentheses isn't. This is clear if we try to replace the first pair of parentheses with the Void keyword.

Not every empty pair of parentheses is a tuple.

What The Swift

I hope this episode has answered any questions you had about the Void keyword. As you can see, the Void keyword is nothing more than a type alias for an empty tuple. Some answers don't need to be complicated.