array
import std::collections::array; — in the prelude · source
Array<T, A>
type struct Array<T, A = GlobalAlloc> {
ptr: T*;
length: u64;
capacity: u64;
alloc: A;
static new() -> Array<T, GlobalAlloc>;
static new_in(alloc: A) -> Array<T, A>;
static with_capacity(capacity: u64) -> Array<T, GlobalAlloc>;
static with_capacity_in(capacity: u64, alloc: A) -> Array<T, A>;
static try_with_capacity_in(capacity: u64, alloc: A) -> Result<Array<T, A>, AllocError>;
length(&this) -> u64;
capacity(&this) -> u64;
is_empty(&this) -> boolean;
get(&this, index: u64) -> Option<T>
where T: Copy;
get_ref(&this, index: u64) -> Option<T*>;
as_ptr(&this) -> T*;
as_slice(&this) -> Slice<T>;
iter(&this) -> implement Iterator<T>
where T: Copy;
iter_ref(&this) -> implement Iterator<T*>;
push(mut &this, value: T) -> void;
try_push(mut &this, value: T) -> Result<(), AllocError>;
pop(mut &this) -> Option<T>;
set(mut &this, index: u64, value: T) -> void
where T: Drop;
swap_remove(mut &this, index: u64) -> T;
first(&this) -> Option<T*>;
last(&this) -> Option<T*>;
index_of(&this, value: &T) -> Option<u64>
where T: Eq;
contains(&this, value: &T) -> boolean
where T: Eq;
reverse(mut &this) -> void;
insert(mut &this, index: u64, value: T) -> void;
remove(mut &this, index: u64) -> T;
truncate(mut &this, new_length: u64) -> void
where T: Drop;
clear(mut &this) -> void
where T: Drop;
sort(mut &this) -> void
where T: Ord;
sort_by(mut &this, less: (&T, &T) -> boolean) -> void;
append(mut &this, source: Slice<T>) -> void
where T: Copy;
try_append(mut &this, source: Slice<T>) -> Result<(), AllocError>
where T: Copy;
resize(mut &this, new_length: u64, value: T) -> void
where T: Copy + Drop;
try_resize(mut &this, new_length: u64, value: T) -> Result<(), AllocError>
where T: Copy + Drop;
reserve(mut &this, additional: u64) -> Result<(), AllocError>;
reserve_exact(mut &this, additional: u64) -> Result<(), AllocError>;
shrink_to_fit(mut &this) -> void;
resize_storage(mut &this, new_capacity: u64) -> Result<(), AllocError>;
}
function from_iter<I, T>(it: I) -> Array<T>
where I: Iterator<T>;
A growable, heap-backed, contiguous sequence. T[] desugars to Array<T>, which is why it is in the prelude. Push and pop at the end are amortized O(1); indexed access is O(1). Growth doubles capacity, starting at 4. The first three fields are laid out to match the T[] fat pointer the compiler emits, so a field declared string[] and an Array<string>::new() agree on every byte offset.
Algorithms that do not need ownership should take a Slice<T> — call as_slice() at the boundary and write the algorithm once.
mut names: Array<String> = Array<String>::new();
names.push(String::from("ada"));
names.push(String::from("grace"));
for (n in names.iter_ref()) {
println(f"{*n}");
}
Constructing
new and with_capacity are backed by GlobalAlloc; the _in forms take your allocator. with_capacity panics on allocation failure — try_with_capacity_in is the recoverable form.
The free function from_iter collects an iterator into a fresh array:
mut squares: Array<i32> = from_iter((0..10).map(square));
It is a free function rather than an Iterator::collect default for a specific reason: a non-self-returning trait default gets cloned into every Iterator impl, including the by-reference cursor over Array<T> — whose clone would instantiate Array<T>, then Array<T*>, then Array<T**>, diverging until it ran out of memory. As a free function only concrete call sites instantiate it.
Reading
getis a bounds-checked read by value and needsT: Copy;get_refis the bounds-checked borrow and is sound for everyT.first/lastborrow, and returnNonewhen empty.index_ofandcontainsare linear scans overT: Eq.
Every pointer, slice, and iterator handed out here is invalidated by any method that may reallocate — push, insert, reserve, shrink_to_fit.
Iterating
iter()(whereT: Copy) yields each element by value.iter_ref()yieldsT*and is sound for everyT. This is how you walk anArray<String>orArray<Box<...>>without cloning.iter_ref().copied()(whereT: Copy) anditer_ref().cloned()(whereT: Clone) turn the borrowing cursor back into a by-value one.
Modifying
| Method | Notes |
|---|---|
push / try_push | Append. try_push returns Result<(), AllocError> instead of panicking. |
pop | Option<T> from the end. |
set(index, value) | Overwrite in place. The previous occupant is dropped first — a raw ptr[i] = v store would leak it. Panics out of range. |
insert(index, value) | Shifts later elements right. index == length appends; panics beyond that. |
remove(index) | Returns T, shifting later elements left — O(n), order preserved. |
swap_remove(index) | Returns T in O(1) by swapping in the last element. Does not preserve order. |
truncate(new_length) | Drops everything past new_length; no-op if already shorter. Keeps capacity. |
clear() | Drops every element and resets the length to zero. Keeps capacity — follow with shrink_to_fit to release it. |
reverse() | In place. Sound for owning T. |
append(source) | Bulk memcpy of a Slice<T>. try_append reserves up front, so a partial copy is impossible. |
resize(new_length, value) | Sets the length exactly, filling new slots with value. try_resize is all-or-nothing. |
reserve / reserve_exact | Result<(), AllocError>. |
shrink_to_fit() | Return unused capacity. |
resize is how you build a fixed-size read buffer. An array only exposes [0, length), so with_capacity alone leaves nothing to read into.
Sorting
sort() (where T: Ord) sorts ascending in place using a hybrid in-place quicksort: median-of-three pivot above a cutoff of 16 elements, insertion sort below it. O(n log n) average, no allocation. Two caveats: it is not stable, and the worst case is O(n²) — v1.0 has no introsort fallback. Owning elements are moved with mem::swap, so the drop obligation stays intact.
sort_by(less) takes your own strict-weak-ordering predicate. It must be a function pointer; non-capturing lambdas convert implicitly, and a capturing closure in method position is rejected (E0458) in v1.0. Capture by indirection, or pull the sort into a free function.
Trait implementations
implement<T, A> trait Drop for struct Array<T, A>
where T: Drop, A: Allocator
implement<T> trait Clone for struct Array<T, GlobalAlloc>
where T: Clone
implement<T> trait Default for struct Array<T, GlobalAlloc>
implement<T, A> trait Eq for struct Array<T, A>
where T: Eq, A: Allocator
implement<T, A> trait Hash for struct Array<T, A>
where T: Hash, A: Allocator
implement<T, A> trait Display for struct Array<T, A>
where T: Display, A: Allocator // std::fmt::display
implement<T, A> trait Debug for struct Array<T, A>
where T: Debug, A: Allocator // std::fmt::display
Clone is a deep copy into a fresh buffer sized to length. Default is a fresh empty array that allocates nothing. Eq is equal length and equal elements in order. Hash folds the length first, so [1, 2] and [1, 2, 0] differ. Display renders [a, b, c] and Debug the same with each element in Debug form; both live in fmt.