Skip to content

Optional Type

Optional values are written as T?.

Int? maybe = 123;
_ same = maybe;

Bar? bar = Bar(x = 1, y = 2)
_ field = bar?.x;

Optional equality is symmetric. If T is equatable, both T? == T and T == T? are valid, as are the corresponding != forms. .none never equals a payload; .some(value) compares its payload.

Int? maybe = 42;
Bool left = maybe == 42;
Bool right = 42 == maybe;

Use ?. to access a field only when the receiver is not null:

_ value = user?.profile?.name;

Use .some(...) to unwrap a present value and .none to match an empty optional:

if maybe is .some(value) {
    print(value);
} else {
    print(0);
}

Mutable and borrowed payload bindings:

if maybe is .some(Int value!) {
    value = value + 1;
}

if maybe is .some(ref Int value) {
    print(value$.get());
}

??

?? provides a fallback value when the optional is empty:

Int value = maybe ?? 42;
Int other = maybe ?? fallback();

The left side must be optional. Use guard for early-exit control flow.

Void print_value(Int? maybe) {
    guard maybe is .some(value) else {
        return ();
    }

    print(value);
    return ();
}

The else block must be non-empty and end in return, break, continue, or throw.

optional$.some() force unwraps an optional through the implicit operation layer:

Int value = maybe$.some();

Ordinary code should prefer .some(...) patterns, guard, or ??.