A value or nil
What you'll learn:
- explain what an optional is and why
Int("42")givesInt?, notInt; - unwrap an optional with
if letandguard let; - supply a default value with
??and read a value through?.; - explain why force unwrapping with
!is dangerous and when it is acceptable.

Imagine someone hands you a gift box. There may be a gift inside, or there may be nothing, and while the box is closed you cannot tell. You cannot use the gift without opening the box: first you open it and look inside.
A program gets boxes like this all the time. Remember type conversion: Int(2.9) always gives the whole number 2. But what if you turn text into a number?
The text "42" holds a number, and the text "forty-two" does not. Swift does not guess and does not stop the program. It answers honestly—with a box that may turn out to be empty:
let first = Int("42")
let second = Int("forty-two")
print(type(of: first)) // Optional<Int>
print(first == nil, second == nil) // false trueLet's go through the program line by line:
Int("42")finds the number42in the text and puts it in the boxfirst.- The text
"forty-two"has no number in it, andInt(…)returns an empty box. Swift writes emptiness as the wordnil. print(type(of: first))prints the type of the box—Optional<Int>, notInt.- Comparing with
nilanswers the question "is the box empty?":firstis not empty, andsecondis.
The type Int?
An optional holds either a value of a given type or nil—"nothing". You write an optional type as an ordinary type with a question mark: Int? reads as "an Int or nothing". The full name of the same type is Optional<Int>, which is what type(of:) showed.
A question mark goes after any type: Double?, String?, Bool?. An optional box has one shape: an Int? holds either a whole number or nothing, but never text.
Where optionals come from
A result that may not exist
Int(…) from text is the first example. The action may fail, and then there is no result. Swift says so through the type: since the result is Int?, it may not be there. Reading the code, you see right away where a check is needed.
A value that does not exist yet
You also declare an optional yourself when the value will appear later. For example, a player's best score is unknown until the first game is played:
var bestScore: Int? = nil
print(bestScore == nil) // true
bestScore = 120
print(bestScore == nil) // falsevar bestScore: Int? = nilcreates an empty box for a whole number. The type must be written here: fromnilalone, Swift cannot tell which box you need.- The first check prints
true: the box is empty. bestScore = 120puts a number in the box. You do not need to wrap it yourself: Swift does that for you.- The second check prints
false.
A plain Int cannot do this. The line let count: Int = nil does not compile: 'nil' cannot initialize specified type 'Int'. An Int always holds a number, and only an optional can be empty.
Int? is not Int
A box with a number is not a number yet. Let's try adding one to first:
print(first + 1) // ✗error: value of optional type 'Int?' must be unwrapped to a value of type 'Int'The compiler refuses to build the program. The message says: a value of type Int? must be unwrapped to get an Int. Unwrapping is exactly opening the box: checking whether there is a value inside and taking it out. While the box is closed, there is nothing to add: what if it holds nil?
Here the box picture is off. You can shake a real box and guess what is inside. The compiler does not allow guessing: even when you are sure first is not empty, you use the value only after unwrapping it.
Why optionals exist
Interviewers like to ask this: "What is an optional, and which mistake does it prevent?" The answer has two parts:
- an optional is a type like
Int?that holds either a value ornil; - the compiler does not let you use an
Int?as anIntuntil the value is unwrapped, so you cannot forget about the empty case.
In many languages almost any value can turn out to be empty. This comes to light only at run time, when the program crashes on the line that used the empty value. In Swift only an optional can be empty, and its type shows that before the program runs.
Common mistake
An optional was printed without unwrapping the value:
print(first) // ✗warning: expression implicitly coerced from 'Int?' to 'Any'This is a warning, so the program runs. But it prints Optional(42), not 42: print shows the box together with its contents, and prints an empty box as the word nil. Unwrap the value first, and print that.
Key points
- An optional
Int?holds either a value of typeIntornil—"nothing". Int("42")givesInt?: the text may contain no number, and then the result isnil.Int?is notInt: until the value is unwrapped, the compiler will not let you treat it as a number.- Only an optional can hold
nil, and printing an optional without unwrapping gives a warning.