Skip to content
Theory · Optionals · lesson 7 of 8

Force unwrapping

You can open a gift box carefully, or you can tear the wrapping off without looking. If the gift is inside, it is in your hands at once. If the box is empty, you are in for a nasty surprise.

In Swift, a ! after an optional does exactly this. The compiler requires you to unwrap the value, and ! is the shortest way to do it:

SWIFT
let typed = "42"
let number = Int(typed)!
print(number + 1) // 43

Let's go through the program line by line:

  1. Int(typed) gives an optional Int? that holds 42.
  2. ! opens the box without checking, and number gets the ordinary number 42 of type Int.
  3. number + 1 adds up without an error, and the program prints 43.

This is not the ! that flips true to false: logical NOT goes before a value (!isVip), unwrapping goes after an optional (Int(typed)!).

Unwrapping with ! is called force unwrapping: the box is opened without checking whether there is anything in it. And what if the text is not a number?

SWIFT
let broken = Int("4x2")! // ✗
print(broken + 1)
TEXT
Fatal error: Unexpectedly found nil while unwrapping an Optional value

The compiler let this program through: it does not check what Int(…) will give. That becomes known only at run time. While running, Int("4x2") gave nil, ! opened the empty box, and the program crashed on this line. The print never ran.

How to read the message

The message has two parts:

  • Fatal error—a crash: the program stopped and does not go on;
  • Unexpectedly found nil while unwrapping an Optional value—"an unexpected nil was found while unwrapping an optional".

In the terminal, the file name and the line number come before the message. A long crash report may follow below it, with the words Illegal instruction, but the cause is named by the Fatal error line. Xcode stops right on the line with ! in this case and shows the same message next to it.

This is not a compile error but a run-time error. The program built, started and stopped only when it reached ! with an empty box.

Here the box picture is off. In real life a torn empty box only disappoints, and the celebration goes on. In Swift, ! on an empty optional stops the whole program.

When ! is acceptable

The value is certainly there

You write ! only when nil is impossible by the program's logic, and its appearance would mean a bug in the code itself. For example, the text is written right in the program, and you can see it holds a number: Int("100")! always gives 100. If such a nil does appear, stopping at once is better than going on with wrong data.

Data from outside

Text from a user, from a file or from the network can turn out to be anything. ! does not fit such data: open their optionals with if let, guard let or ??. Then an empty box sends the program down a separate branch or is replaced by a default value instead of stopping the work.

Interviewers like to ask this: "Why is ! dangerous, and when may you write it?" The answer has two parts:

  • ! on nil crashes the program at run time, and the compiler does not catch it;
  • ! fits only when nil is impossible by the program's logic; in all other cases the value is unwrapped safely.

Common mistake

! was expected to give zero instead of emptiness:

SWIFT
let stock: Int? = nil
print(stock! + 5) // ✗

The expected output was 5, as if ! turned nil into 0. But ! does not make up a value: the program crashes with the same Fatal error. If you need zero instead of nil, say so: (stock ?? 0) + 5 gives 5.

Key points

  • ! unwraps the value of an optional without a check: Int("42")! gives 42 of type Int.
  • ! on nil crashes the program with the message Fatal error: Unexpectedly found nil while unwrapping an Optional value.
  • The compiler does not catch this error: it happens at run time, on the line with !.
  • Write ! only when nil is impossible by the program's logic, and open data from outside with if let, guard let or ??.