Skip to content

Option

Transform and recover optional values without panics.

Updated View as Markdown

Option[T], also spelled T?, represents a value that may be absent. It has exactly two variants:

enum Option[T] {
    Some(T)
    None
}

Use Option instead of a sentinel such as -1, an empty string, or a null pointer. The type forces the caller to account for absence. Its methods are total: the prelude deliberately has no panic-style unwrap() or expect().

Inspection

The inspection methods do not extract the payload:

Method Result
is_some() Whether the value is Some
is_none() Whether the value is None
is_some_and(predicate) Whether it is Some and the payload passes the predicate
if value.is_some_and(item => item.active) {
    publish()
}

Use match when the payload is needed or the variants require distinct work:

match account.nickname {
    Some(name) => println(name)
    None => println(account.full_name)
}

Fallbacks

label := maybe_label.unwrap_or("untitled")
config := cached.unwrap_or_else(() => load_default())

unwrap_or evaluates its argument eagerly. unwrap_or_else calls its closure only for None.

This evaluation distinction matters when the default allocates, performs I/O, or otherwise does real work:

config := cached.unwrap_or_else(() => load_default())

Prefer unwrap_or for an already-available value and unwrap_or_else for a computed fallback.

Transformations

length := maybe_name
    .filter(name => !name.is_blank())
    .map(name => name.length())

map preserves the optional wrapper. flat_map is for a callback that already returns Option. filter keeps a present value only when its predicate holds. Call flatten on a nested option to collapse Option[Option[T]] into Option[T].

owner := maybe_project.flat_map(project => project.owner)

Use map when the callback returns a plain value and flat_map when it can itself report absence. That choice avoids accumulating wrappers such as Option[Option[T]].

Combining

The combining methods differ in what they preserve:

Method If self is Some If self is None
or(other) Keep self Use other
or_else(f) Keep self Call f()
and(other) Use other Return None
zip(other) Pair both present values Return None

zip is useful when two independently optional inputs are both required:

point: (int, int)? = x.zip(y)

Like unwrap_or, or receives an already-evaluated value. or_else is the lazy form.

Conversion

to_result(error) maps absence into a typed failure. to_list() produces zero or one elements.

fn require_name(value: string?): string ! ValidationError {
    return value.to_result(MissingName)?
}

This is the boundary between “not present” and “operation failed.” Preserve Option when absence is expected. Convert to Result when the current operation requires a value and needs to explain why it cannot continue.

Equality and hashing

Options are equatable when T is equatable and hashable when T is hashable. The variant contributes to the hash, so None and a present value remain distinct map keys. to_string() renders the variant as None or Some(value).

None == None; Some(left) == Some(right) delegates to the payload’s equality implementation. None never equals Some.

For pattern-based extraction, optional loop conditions, and ?, see Option errors.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close