Sling Academy
Home/Rust/Resizing vectors in Rust: resize, extend, and extend_from_slice

Resizing vectors in Rust: resize, extend, and extend_from_slice

Last updated: January 04, 2025

When working with vectors in Rust, there often comes a time when you need to resize them. Fortunately, Rust provides several methods that can help with growing or shrinking vectors: resize, extend, and extend_from_slice. This article explores these methods through explanations and examples, guiding you on when and how to use each.

Understanding Vectors in Rust

A vector in Rust, represented as Vec<T>, is a growable array type. It is a dynamic array that can change size at runtime, and its elements are stored contiguously in memory. You can initialize a vector using the Vec::new() function, or by using the handy vec![] macro with initial values.

let mut numbers = vec![1, 2, 3, 4, 5]; // A vector of integers

Resizing with Vec::resize

The resize method allows you to specify the length you want the vector to be. If the new size is greater than the current size, resize appends additional elements to the vector, each initialized to a particular value. If the new size is less, it removes elements from the end of the vector.

let mut vec = vec![1, 2, 3];
vec.resize(5, 0); // vec becomes [1, 2, 3, 0, 0]
vec.resize(2, 0); // vec becomes [1, 2]

In this example, the vector initially contains three elements. Using resize(5, 0), two new elements initialized to 0 are added. When resizing to 2, it cuts off elements from the end.

Extending a Vector with Vec::extend

The extend method lets you grow the vector by appending elements from an iterable. This method is useful for adding multiple elements without repeating push.

let mut vec = vec![1, 2, 3];
vec.extend(&[4, 5, 6]);
// vec is now [1, 2, 3, 4, 5, 6]

With extend, you can add a slice, array, or another vector, as long as they implement the IntoIterator trait. This flexibility makes extend an efficient option for concatenating sequences.

Appending Slices Using Vec::extend_from_slice

The extend_from_slice is specifically optimized for slices, as it directly appends elements from one slice into the vector. It's a more efficient choice when you are certain you'll be extending from a slice.

let mut vec = vec![1, 2, 3];
let slice = &[4, 5, 6];
vec.extend_from_slice(slice);
// vec is now [1, 2, 3, 4, 5, 6]

This example directly appends the elements of the slice to the vector. extend_from_slice is particularly useful for working with fixed-size arrays.

Choosing Between resize, extend, and extend_from_slice

When deciding which method to use for resizing, consider the following:

  • Use resize: When you want to change the vector to a specific size and require initialization of new elements.
  • Use extend: For appending elements from chains or iterators, providing versatility in what you can add to the vector.
  • Use extend_from_slice: When you have a known slice of elements that can be quickly appended to the vector for better performance.

Each method has particular use cases where they shine, offering flexibility in handling sequences in Rust. Understanding these differences will allow you to write more efficient and idiomatic Rust code.

Conclusion

Resizing vectors in Rust can be effectively handled by resize, extend, and extend_from_slice, depending on your needs. By choosing the right method, you can manage vector sizes with precision, whether you're adding pre-initialized elements, working with iterables, or optimizing with slices. This flexibility makes Rust's vector capabilities powerful, allowing for diverse data handling and manipulation in a performant manner.

Next Article: Rust Slicing vectors: &vec[..], &vec[a..b], and advanced slice patterns

Previous Article: Rust - Understanding capacity, reserve, and shrink_to_fit in Vec

Series: Collections in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior