Skip to content
Educora
Intermediate16 min4 / 14

Optionals: when a value may be missing

Handle the “no value” case safely in Swift with optionals: `nil`, `if let`, `guard let`, `??` and optional chaining.

Check yourself
In this lesson you will learn
  • Explain what an optional type (Int?, String?) and nil are
  • Unwrap an optional safely with if let and guard let
  • Give a default value with ?? and use optional chaining with ?.

Some of the contacts on your phone have an email address and some don't. A user may type “fifteen” instead of “15” into an age field — and that text cannot be turned into a number. Programs meet such “no value” situations every day. In many languages they cause unexpected crashes, but Swift has a special tool for them — optionals.

What is an optional?

Definition
Optional

A type that either holds a value of some type or holds nothing (nil). It is written with a question mark after the type name: Int? means “either an Int or nil”.

A plain Int variable can never be empty — Swift guarantees it. If a value might be missing, the type is declared optional. For example, Int("42") tries to turn a string into a number, and the result has the type Int?, because the conversion may fail.

Swift
let age = Int("42")
let wrong = Int("hello")
var middleName: String? = nil
middleName = "Ali"

print(age)
print(wrong)
print(middleName)
Expected output
Optional(42)
nil
Optional("Ali")

Notice that when an optional is printed, the value appears inside an Optional(...) “box”, and Xcode shows a yellow warning. To use the value in the box, you first have to unwrap it. You cannot simply write age + 1, because you cannot add an Int? and an Int.

Unwrapping with `if let` and `guard let`

if let checks: if there is a value inside the optional, it stores it in a new constant and runs the block; if it is nil, the else block runs. Inside the block, number is already a plain Int.

Swift
let input = "15"

if let number = Int(input) {
    print("Next year you will be \(number + 1).")
} else {
    print("That is not a number.")
}

let nickname: String? = nil
if let nickname {
    print("Hi, \(nickname)!")
} else {
    print("No nickname yet.")
}
Expected output
Next year you will be 16.
No nickname yet.

guard let works the other way round: if there is no value, the else block runs, and it must leave the current code (with return, break or continue). If there is a value, the unwrapped name can be used in all the code after the guard. It is usually used in functions — a function is a named block of code that you will study in detail in a later lesson.

Swift
func greet(_ name: String?) {
    guard let name else {
        print("Hello, guest!")
        return
    }
    print("Hello, \(name)!")
    print("Your name has \(name.count) letters.")
}

greet("Aysel")
greet(nil)
Expected output
Hello, Aysel!
Your name has 5 letters.
Hello, guest!

`??` and optional chaining

The ?? operator gives a default value: if there is a value on the left, it is used; if it is nil, the value on the right is used. ?. is optional chaining: it accesses a property or method of an optional only when there is a value, and when it is nil, the whole expression quietly returns nil.

Swift
let savedName: String? = nil
let displayName = savedName ?? "Anonymous"
print(displayName)
print(Int("abc") ?? 0)

let email: String? = "leyla@example.com"
let noEmail: String? = nil
print(email?.count)
print(noEmail?.count)
print(email?.uppercased() ?? "no email")
print(noEmail?.uppercased() ?? "no email")
Expected output
Anonymous
0
Optional(17)
nil
LEYLA@EXAMPLE.COM
no email

Notice that email?.count returns an Int?, not a plain Int — if one link in the chain can be nil, the result is optional too. That is why ?. and ?? are often used together.

WayWhat it doesSafe?
if let x = optruns the block if there is a valueyes
guard let x = opt else { … }leaves the code if there is no valueyes
opt ?? defaultgives a default instead of nilyes
opt?.propertyaccesses only when there is a valueyes
opt!force-unwraps; crashes on nilno
Ways to unwrap an optional

Key points

  • A T? type holds either a value of type T or nil; plain types are never nil.
  • if let runs a block when there is a value; guard let leaves the code when there isn't.
  • ?? gives a default instead of nil: Int("abc") ?? 0 → 0.
  • The result of ?. chaining is also optional.
  • Force-unwrapping with ! crashes the program on nil — avoid it.

Check yourself

10 questions. Every correct answer earns XP.

1 / 10
What is the type of Int("25")?