Stack-allocated arrays
arrayvec
Arrays that are ONLY stack-allocated with fixed capacity.
use arrayvec::ArrayVec;
// ArrayVec is a vector backed by a fixed size array.
// The capacity is of type usize but is range limited to u32::MAX
// It offers a simple API but also dereferences to a slice, so that the full
// slice API is available.
fn main() {
let mut array = ArrayVec::<_, 2>::new();
assert_eq!(array.capacity(), 2);
// Push some elements into the ArrayVec
array.push(1);
array.push(2);
assert!(array.is_full());
// Trying to push beyond the capacity will result in a panic
// ERROR: array.push(3);
let overflow = array.try_push(3);
assert!(overflow.is_err());
// Access elements
for i in 0..array.len() {
println!("Element at index {}: {}", i, array[i]);
}
assert_eq!(&array[..], &[1, 2]);
let mut array2: ArrayVec<i32, 3> = ArrayVec::from([1, 2, 3]);
// Pop an element from the ArrayVec
if let Some(value) = array2.pop() {
println!("Popped value: {}", value);
}
assert_eq!(array2.len(), 2);
assert!(!array2.is_empty());
}
smallvec
Arrays that are stack-allocated with fallback to the heap if the fixed stack capacity is exceeded.
use smallvec::SmallVec;
use smallvec::smallvec;
fn main() {
// Create a SmallVec with a small inline capacity of 4
let mut small_vec: SmallVec<i32, 4> = SmallVec::new();
// Push some elements into the SmallVec
small_vec.push(1);
small_vec.push(2);
small_vec.push(3);
small_vec.push(4);
// You can also initialize it via a macro:
let mut small_vec: SmallVec<i32, 4> = smallvec![1, 2, 3, 4];
// Print the current state of the SmallVec
println!("SmallVec (inline): {:?}", small_vec);
// Push beyond the inline capacity, causing a heap allocation
small_vec.push(5);
// Print the state of the SmallVec after pushing beyond capacity
println!("SmallVec (heap-allocated): {:?}", small_vec);
// Access elements
for i in 0..small_vec.len() {
println!("Element at index {}: {}", i, small_vec[i]);
}
// Pop an element from the SmallVec
if let Some(value) = small_vec.pop() {
println!("Popped value: {}", value);
}
// Print the state of the SmallVec after popping
println!("SmallVec after popping: {:?}", small_vec);
// Split off the SmallVec
let mut small_vec2 = small_vec.split_off(1);
assert_eq!(small_vec, [1]);
assert_eq!(small_vec2, [2, 3, 4]);
// SmallVec points to a slice, so you can use normal slice
// indexing and other methods to access its contents:
small_vec2[0] = small_vec2[1] + small_vec2[2];
small_vec2.sort();
}
tinyvec
The tinyvec
crate provides a way to work with vectors that can store a small number of elements inline, without heap allocation, and dynamically grow to the heap if necessary. It is in 100% safe Rust code. It's similar to smallvec
but with a smaller feature set and no dependencies. tinyvec
requires items to implement the Default
trait.
use tinyvec::TinyVec;
fn main() {
// Create a TinyVec with an inline capacity of 4 elements
let mut tiny_vec: TinyVec<[i32; 4]> = TinyVec::new();
// Push some elements into the TinyVec
tiny_vec.push(1);
tiny_vec.push(2);
tiny_vec.push(3);
tiny_vec.push(4);
// Print the current state of the TinyVec
println!("TinyVec (inline): {:?}", tiny_vec);
// Push beyond the inline capacity, causing a heap allocation
tiny_vec.push(5);
// Print the state of the TinyVec after pushing beyond capacity
println!("TinyVec (heap-allocated): {:?}", tiny_vec);
// Access elements
for i in 0..tiny_vec.len() {
println!("Element at index {}: {}", i, tiny_vec[i]);
}
// Pop an element from the TinyVec
if let Some(value) = tiny_vec.pop() {
println!("Popped value: {}", value);
}
// Print the state of the TinyVec after popping
println!("TinyVec after popping: {:?}", tiny_vec);
}
[stack_allocated_arrays: write (P1)](https://github.com/john-cd/rust_howto/issues/282)