option
Optional values.The Option
type represents an optional value: every Option
is either Some
and contains a value, or None
, and does not. Option
types are very common in Cairo code, as they have a number of uses:Initial values * Return values for functions that are not defined over their entire input range (partial functions) * Return value for otherwise reporting simple errors, where None
is returned on error * Optional struct fields * Optional function argumentsOptions are commonly paired with pattern matching to query the presence of a value and take action, always accounting for the None
case.
fn divide(numerator: u64, denominator: u64) -> Option<u64> {
if denominator == 0 {
None
} else {
Some(numerator / denominator)
}
}
// The return value of the function is an option
let result = divide(2, 3);
// Pattern match to retrieve the value
match result {
// The division was valid
Some(x) => println!("Result: {x}"),
// The division was invalid
None => println!("Cannot divide by 0"),
}
The question mark operator, ?
Similar to the Result
type, when writing code that calls many functions that return the Option
type, handling Some
/None
can be tedious. The question mark operator, ?
, hides some of the boilerplate of propagating values up the call stack.It replaces this:
fn add_last_numbers(mut array: Array<u32>) -> Option<u32> {
let a = array.pop_front();
let b = array.pop_front();
match (a, b) {
(Some(x), Some(y)) => Some(x + y),
_ => None,
}
}
With this:
fn add_last_numbers(mut array: Array<u32>) -> Option<u32> {
Some(array.pop_front()? + array.pop_front()?)
}
It's much nicer!Ending the expression with ?
will result in the Some
's unwrapped value, unless the result is None
, in which case None
is returned early from the enclosing function. ?
can be used in functions that return Option
because of the early return of None
that it provides.Some
: Some None
: None # Method overviewIn addition to working with pattern matching, Option
provides a wide variety of different methods. ## Querying the variantThe is_some
and is_none
methods return true
if the Option
is Some
or None
, respectively.is_none
: OptionTrait::is_none is_none_or
: OptionTrait::is_none_or is_some
: OptionTrait::is_some is_some_and
: OptionTrait::is_some_and ## Extracting the contained valueThese methods extract the contained value in an Option<T>
when it is the Some
variant. If the Option
is None
:expect
panics with a provided custom message * unwrap
panics with a generic message * unwrap_or
returns the provided default value * unwrap_or_default
returns the default value of the type T
(which must implement the Default
trait) * unwrap_or_else
returns the result of evaluating the provided functionexpect
: OptionTrait::expect unwrap
: OptionTrait::unwrap unwrap_or
: OptionTrait::unwrap_or unwrap_or_default
: OptionTrait::unwrap_or_default unwrap_or_else
: OptionTrait::unwrap_or_else ## Transforming contained valuesThese methods transform Option
to Result
:ok_or
transforms Some(v)
to Ok(v)
, and None
to Err(err)
using the provided default err
value. * ok_or_else
transforms Some(v)
to Ok(v)
, and None
to a value of Err
using the provided functionErr(err)
: Err Ok(v)
: Ok Some(v)
: Some ok_or
: OptionTrait::ok_or ok_or_else
: OptionTrait::ok_or_elseThese methods transform the Some
variant:map
transforms Option<T>
to Option<U>
by applying the provided function to the contained value of Some
and leaving None
values unchangedThese methods transform Option<T>
to a value of a possibly different type U
:map_or
applies the provided function to the contained value of Some
, or returns the provided default value if the Option
is None
* map_or_else
applies the provided function to the contained value of Some
, or returns the result of evaluating the provided fallback function if the Option
is None
map_or
: OptionTrait::map_or map_or_else
: OptionTrait::map_or_else ## Boolean operatorsThese methods treat the Option
as a boolean value, where Some
acts like true
and None
acts like false
. There are two categories of these methods: ones that take an Option
as input, and ones that take a function as input (to be lazily evaluated).The and
, or
, and xor
methods take another Option
as input, and produce an Option
as output. Only the and
method can produce an Option<U>
value having a different inner type U
than Option<T>
.| method | self | input | output | |---------|-----------|-----------|-----------| | and
| None
| (ignored) | None
| | and
| Some(x)
| None
| None
| | and
| Some(x)
| Some(y)
| Some(y)
| | or
| None
| None
| None
| | or
| None
| Some(y)
| Some(y)
| | or
| Some(x)
| (ignored) | Some(x)
| | xor
| None
| None
| None
| | xor
| None
| Some(y)
| Some(y)
| | xor
| Some(x)
| None
| Some(x)
| | xor
| Some(x)
| Some(y)
| None
|and
: OptionTrait::and or
: OptionTrait::or xor
: OptionTrait::xorThe and_then
and or_else
methods take a function as input, and only evaluate the function when they need to produce a new value. Only the and_then
method can produce an Option<U>
value having a different inner type U
than Option<T>
.| method | self | function input | function result | output | |--------------|-----------|----------------|-----------------|-----------| | and_then
| None
| (not provided) | (not evaluated) | None
| | and_then
| Some(x)
| x
| None
| None
| | and_then
| Some(x)
| x
| Some(y)
| Some(y)
| | or_else
| None
| (not provided) | None
| None
| | or_else
| None
| (not provided) | Some(y)
| Some(y)
| | or_else
| Some(x)
| (not provided) | (not evaluated) | Some(x)
|and_then
: OptionTrait::and_then or_else
: OptionTrait::or_else ## Iterating over Option
An Option
can be iterated over. This can be helpful if you need an iterator that is conditionally empty. The iterator will either produce a single value (when the Option
is Some
), or produce no values (when the Option
is None
). For example, into_iter
contains Some(v)
if the Option
is Some(v)
, and None
if the Option
is None
.
Fully qualified path: core::option