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.