Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Handle allocation failures

Collection construction returns Result[collection, AllocError]. Use ? to propagate a failure, or match to recover:

def answers() -> Result[list[i64], AllocError]:
    mut values = list[i64].with_capacity(2)?
    values.append(21)?
    values.append(42)?
    Ok(values)

def main() -> Result[(), IoError]:
    match answers():
        case Ok(values):
            print(values)?
        case Err(AllocError.OutOfMemory):
            print("not enough memory")?
        case Err(AllocError.CapacityOverflow):
            print("requested capacity is too large")?
    Ok(())
[21, 42]

list[i64].with_capacity(2)? constructs an empty list with room for at least two elements. Appending those elements needs no further list storage allocation. Use list[i64]() when you do not know the capacity ahead of time. dict[str, i64]() and set[str]() construct the other collection kinds. Displays such as [21, 42] return the same kind of allocation result; extract their collection with ? too. List displays reserve their full element count automatically. Both mutable and immutable list bindings benefit. Element expressions may still allocate.

For an existing mutable collection, values.reserve(n)? reserves room for n additional elements beyond its current length. Existing contents remain unchanged if reservation fails.

Growth also returns a result: append for lists, insert for dictionaries, and add for sets. A failed insertion keeps existing contents but consumes its arguments, cleaning up any owned argument rather than returning it.

AllocError has two payload-free variants. OutOfMemory means the allocator rejected a request. CapacityOverflow means its size cannot be represented. Neither variant needs allocation.

Use capacity and reservation to obtain storage before inserting values you want to keep if reservation fails.