Swift’s gems: nil, Void and Never

Learn what are nil, Void and Never in Swift

Radu Dan
4 min readMay 18, 2019

Motivation

This article provides a concise overview of nil, Void, and Never in Swift terminology. We will explore the basic usage of these three gems to ensure you have a clear understanding of their differences.

nil

The absence of a value.

When we mention nil, we are addressing Swift's optionals.

Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. [1]

Under the hood, an Optional is defined as an enum:

enum Optional<Wrapped>: ExpressibleByNilLiteral {
case none
case some(Wrapped)
}

Example:

let greeting: String? = nil // preferred
let greeting2: String? = .none // same thing
let greeting3: Optional<String> = .none // same thing

Void

A return type that doesn’t return a value.

Void is implemented as an empty tuple: typealias Void = (). This is the default return type for functions or closures unless specified otherwise.

Example #1:

func doSomeStuff() {
// magic stuff
}

This is equivalent to:

func doSomeStuff() -> Void {
// magic stuff
}

Example #2:

func doSomeStuff() {} // preferred
func doSomeStuff2() -> Void {} // same thing
func doSomeStuff3() -> () {} // same thing

Example #3:

func doSomeStuff(completion: () -> Void) {
// magic stuff
}

In this example, we have a closure that takes an argument of type Void and returns Void (no values).

Could we have written completion: (Void) -> ()? Yes, but if you are using Swift 4 or above, you will receive a compile warning:

The compiler encourages us to remove the Void type. As the language has evolved, tuples are now subject to stricter handling.

But is completion: (Void) -> () the same as completion: () -> ()? Let's see:

func doSomeStuff(completion: (Void) -> ()) {}
func doSomeStuff2(completion: () -> ()) {}

And call the methods from outside:

func outside() {
doSomeStuff { result in
// some closure stuff
}

doSomeStuff2 {
// some closure stuff
}
}

The first closure in doSomeStuff returns a parameter with the value Void, while the second closure does not return anything.

You can attempt to write result in for the second function, but the compiler will give you an error:

Never

Something that will never return.

Never signifies that a function will never return. Introduced in Swift 3, it replaced the @noreturn attribute with an empty type. It is implemented as an empty enum:

enum Never {}

For further details, you can read the documentation here.

Never helps the compiler understand which functions will never return a value. This brings us to the distinction between Never and Void.

Void vs Never

Never informs the compiler that there is no need to return a value. It is used in methods that will unconditionally throw an error or crash the system.

Never cannot be constructed; it is an uninhabited type.

  • Implementation: Void is a tuple, while Never is an empty enum.
  • Never informs the compiler that there is no need to return a value.
  • Never is used in methods that will unconditionally throw an error or crash the system.
  • Never cannot be constructed, is an uninhabited type [2].

Common usages:

Example #1 — fatalError

func dumpAndCrush() -> Never {
// export output to log
// save
fatalError("App went dark! Check the logs for details.")
}

// fatalError declaration
func fatalError(
_ message: @autoclosure () -> String = String(),
file: StaticString = #file,
line: UInt = #line
) -> Never

Example #2 — preconditionFailure

func doSomeStuff(with numbers: [Int]) {
guard numbers.count > 5 else {
preconditionFailure("More than five numbers are required!")
}
// do some stuff
}

// preconditionFailure declaration
func preconditionFailure(
_ message: @autoclosure () -> String = String(),
file: StaticString = #file,
line: UInt = #line
) -> Never

Conclusion

We have explored the common usages of Swift’s nil, Void, and Never. While Never is the least common of the three and may initially appear similar to Void, we have established that they serve different purposes.

Optionals lie at the heart of Swift APIs and are used extensively. It is crucial to understand their purpose and functionality. For beginners seeking to understand optionals better, I recommend this excellent article: Swift Optionals Explained Simply.

nil denotes the absence of a value, Void indicates a return type that doesn't return a value, and Never signifies something that will never return.

  • nil is the absence of a value
  • Void is a return type that doesn’t return a value
  • Never is something that will never return

--

--

Radu Dan
Radu Dan

Written by Radu Dan

iOS Developer / Doing magic things in Swift

No responses yet