Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

When there might be nothing

Some things might not be there. string? is the type that says so: a string, or nothing at all.

struct Profile {
    name: string
    email: string?
}

name is always there. email might not be, and the ? is the whole difference. Nothing else in the program can forget it — there is no path where an absent email arrives looking like a string.

Getting at the value

match takes both cases:

func greet(p: Profile?) -> string {
    match p {
        Profile as found => return "hello {found.name}"
        none => return "nobody here"
    }
}

The shorter form tests with x? and names the value with as:

func shout(p: Profile?) -> string {
    if p? as found {
        return "HELLO {found.name}"
    }
    return "nobody here"
}

as found names what the test just proved exists, and found is a plain Profile inside the block.

Without as, x? is just a bool:

func anybody(p: Profile?) -> string {
    if p? {
        return "yes"
    }
    return "no"
}

?? supplies the other branch

Most of the time you don’t want to branch, you want a value either way. ?? gives the right side when the left is absent:

func email_of(p: Profile) -> string {
    return p.email ?? "no email"
}

The right side can also leave instead of producing a value — ?? return, ?? break, ?? continue. There’s no binder, because there’s nothing to bind: absence carries no payload.

Chaining with ?.

p?.email reads email when p is there and gives none when it isn’t — no branch, no binder:

func email_or(p: Profile?, fallback: string) -> string {
    return p?.email ?? fallback
}

Two things can be missing here: the profile, and the email on it. p?.email is a string? all the same, not two layers of absence — “no profile” and “a profile with no email” are the same answer to whoever asked for an email. So one ?? finishes the job.

A longer chain works the same way: every link short-circuits, and the end of it is still one layer.

Running it

The code above is one program, and it prints:

hello ada
nobody here
HELLO ada
nobody here
yes
no
[email protected]
no email
[email protected]
unknown
unknown

Rules behind this page

  • Optionals: T?, none, and the ? family
  • Error types: the other shape, where the second branch carries a reason