Skip to content
CryoCryo home
Stdlibcore

option

import std::core::option; — in the prelude · source

Option<T>

type enum Option<T> {
    Some(T);
    None;
}

implement enum Option<T> {
    is_some(&this) -> boolean;
    is_none(&this) -> boolean;
    as_ref(&this) -> Option<T*>;
    unwrap_ptr(&this) -> T*;
    ![sink]
    unwrap(&this) -> T;
    ![sink]
    expect(&this, message: string) -> T;
    ![sink]
    unwrap_or(&this, default_value: T) -> T;
    ![sink]
    unwrap_or_else(&this, default_fn: () -> T) -> T;
    ![sink]
    map<U>(&this, f: (T) -> U) -> Option<U>;
    ![sink]
    and_then<U>(&this, f: (T) -> Option<U>) -> Option<U>;
    ![sink]
    or_else(&this, f: () -> Option<T>) -> Option<T>;
    take(mut &this) -> Option<T>;
    ![sink]
    ok_or<E>(&this, err: E) -> Result<T, E>;
    ![sink]
    ok_or_else<E>(&this, err_fn: () -> E) -> Result<T, E>;
    contains(&this, value: &T) -> boolean
    where T: Eq;
}

Option<T> is how Cryo says "there might not be a value here". It replaces the nullable pointer: the compiler will not let you reach the payload without handling the absent case.

match (maybe_port) {
    Option::Some(p) => { println(f"port {p}"); }
    Option::None    => { println("no port configured"); }
}

The ![sink] attribute marks the methods that consume the receiver: after opt.unwrap() the move-checker treats opt as moved, even though the parameter is spelled &this. The unmarked methods leave the receiver live.

Querying and unwrapping

MethodReturnsNotes
is_some / is_noneboolean
unwrapTPanics on None.
expect(message)TPanics with your message on None.
unwrap_or(default_value)TReturns default_value on None.
unwrap_or_else(default_fn)TComputes the fallback only when needed.

Borrowing without consuming

unwrap and friends take the value out. When the payload owns heap storage and you only want to look at it, borrow instead:

  • as_ref(&this) -> Option<T*>Some(v) becomes Some(&v), None stays None. The pointer aliases the receiver's payload rather than copying it, so the receiver keeps ownership.
  • unwrap_ptr(&this) -> T* — the same borrow, aborting on None, and one less layer to unwrap.

Both pointers are invalidated by anything that moves or overwrites the receiver.

Transforming

MethodReturns
map<U>(f)Option<U>
and_then<U>(f)Option<U>
or_else(f)Option<T>
take()Option<T> — replaces the receiver with None and returns what was there
ok_or<E>(err)Result<T, E>
ok_or_else<E>(err_fn)Result<T, E>
contains(value) (where T: Eq)boolean

The ?? operator is sugar over the same idea: opt ?? fallback yields the payload or fallback, evaluating the fallback only on None.

Trait implementations

implement<T> trait Clone for enum Option<T>
where T: Clone

implement<T> trait Eq for enum Option<T>
where T: Eq

implement<T> trait Display for enum Option<T>
where T: Display   // std::fmt::display

implement<T> trait Debug for enum Option<T>
where T: Debug   // std::fmt::display

Display and Debug both render Some(...) / None; the difference is which trait the payload goes through.