patternrustTip
Vec<T> vs &[T]: owned growable array vs borrowed slice
Viewed 0 times
VecslicearraycollectionDerefcoercioncapacity
Problem
Functions unnecessarily take Vec<T> as parameters, requiring callers to give up ownership or clone their data when read-only access would suffice.
Solution
Accept &[T] in function signatures to work with both Vec<T> and array slices without cloning:
// Prefer &[T] for read-only parameters
fn sum(values: &[i32]) -> i32 {
values.iter().sum()
}
let v = vec![1, 2, 3, 4];
let arr = [5, 6, 7];
println!("{}", sum(&v)); // &Vec<i32> coerces to &[i32]
println!("{}", sum(&arr)); // &[i32; 3] coerces to &[i32]
// Use Vec<T> when you need to own, grow, or return a collection
fn doubled(values: &[i32]) -> Vec<i32> {
values.iter().map(|x| x * 2).collect()
}
// Mutable slice for in-place modification
fn zero_out(values: &mut [i32]) {
for v in values.iter_mut() { *v = 0; }
}Why
&[T] is a fat pointer (address + length) to a contiguous sequence of T values. Vec<T> owns heap memory and tracks capacity too. &Vec<T> coerces to &[T] via Deref, so accepting &[T] is strictly more general.
Gotchas
- Vec<T> has three fields: pointer, length, capacity. &[T] has two: pointer, length
- Slices cannot grow — any operation that would reallocate requires a Vec<T>
- Use &mut [T] when you need to mutate elements in place but not resize
Revisions (0)
No revisions yet.