Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Special pages
JOHNWICK
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Vectors
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
After getting cozy with enums and pattern matching in our previous days, it’s time to turn our attention to another Rust superstar: vectors. If you missed yesterday’s writeup, you can check out the link below. Pattern Matching with Enums Yesterday, we looked into Rust enums, seeing how they can be used for modelling choices, states, and even data-packed… medium.com If enums are about choosing between distinct options, vectors are about gathering a bunch of items in one place, ready to grow or shrink as needed. Think of vectors as a dynamic backpack for your data, unlike the fixed-size shoebox of arrays. In this guide, we’ll discuss what makes vectors useful, how they differ from arrays, and how to use them in fun, practical ways. Let’s start by getting to know vectors and their place in Rust. What Are Vectors? Vectors in Rust, written as Vec<T>, are like a stretchy list that can hold any number of items of the same type. Need to store a collection of scores, names, or game items? A vector’s is all you need, and it can expand or contract as your program runs. Unlike some other languages where lists might feel like a free-for-all, Rust’s vectors are tightly managed, ensuring safety and performance. You create a vector with Vec::new() or the handy vec! macro, like this: <pre> // Empty vector let scores: Vec<i32> = Vec::new(); // Vector with initial values let names = vec!["Alice", "Bob", "Charlie"]; </pre> Here, scores is an empty vector ready to hold i32 numbers, while names starts with three strings. The T in Vec<T> means you can store any type, as long as all elements match that type. But how do vectors compare to arrays, which we’ve all seen before? Let’s clear that up next. Vectors vs. Arrays Key Differences Arrays and vectors might seem like cousins, but they’re built for different jobs. An array in Rust, like [i32; 3], is a fixed-size collection, like a shelf with exactly three slots, no more, no less. Once you set its size, it’s locked in. Vectors, on the other hand, are dynamic, growing or shrinking as you add or remove items. Here’s a quick comparison: <pre> let array = [1, 2, 3]; // Fixed size: 3 elements let mut vector = vec![1, 2, 3]; // Can grow or shrink vector.push(4); // Vector now has 4 elements // array.push(4); // Nope, arrays can’t do this! </pre> Arrays live on the stack, making them super fast for small, fixed collections, but they’re rigid. Vectors live on the heap, which gives them the flexibility to change size but comes with a slight performance cost. Arrays are great for things like RGB colors ([u8; 3]) where the size never changes, while vectors shine for lists that evolve, like a player’s inventory in a game. With this distinction in mind, let’s see how to create and fill vectors. Creating and Populating Vectors Vectors are easy to set up, and Rust gives you a few ways to get started. You can create an empty vector with Vec::new() or use the vec! macro for instant initialization: <pre> let mut numbers: Vec<i32> = Vec::new(); // Empty, ready for action numbers.push(10); // Add one element numbers.push(20); // Add another let fruits = vec!["apple", "banana", "orange"]; // Pre-filled vector </pre> The mut keyword is necessary if you want to modify the vector, like adding elements with push. You can also create a vector with a specific capacity using Vec::with_capacity(n) to optimize performance if you know roughly how many items you’ll store. For example: let mut buffer: Vec<u8> = Vec::with_capacity(100); // Room for 100 bytes Once your vector is ready, you’ll want to add, remove, or access elements. Let’s check out the common operations that make vectors so handy. Common Vector Operations Vectors come with various methods to manage your data. Here are some of the most useful ones, using a game inventory as an example: <pre> let mut inventory = vec!["sword", "shield", "potion"]; inventory.push("ring"); // Add "ring" to the end inventory.pop(); // Remove and return "ring" inventory[1] = "armor"; // Replace "shield" with "armor" let first = inventory.get(0); // Get "sword" as Option<&str> </pre> * Push and Pop: push adds an item to the end, while pop removes and returns the last item, returning an Option<T> (Some(item) or None if empty). * Indexing — Use inventory[i] to access or modify an element directly, but beware—Rust will panic if the index is out of bounds. * Safe Access: get(i) is safer, returning Some(&item) or None if the index doesn’t exist. * Length and Capacity: Check len() for the current number of elements and capacity() for the allocated space. You can also iterate over a vector to process each item: <pre> for item in &inventory { println!("Found item: {}", item); } </pre> This loop borrows each item, keeping the vector intact. If you need to modify elements while iterating, use &mut inventory. These operations make vectors flexible for all sorts of tasks, but what happens when you need to work with vectors in a real program? Let’s look at some practical examples. Vectors in Real-World Scenarios Vectors are perfect for dynamic scenarios where data grows or changes. Imagine a game where players collect items in their inventory: <pre> let mut inventory = vec!["sword", "shield"]; inventory.push("potion"); if inventory.len() < 5 { println!("Inventory not full yet, {} slots left!", 5 - inventory.len()); } else { println!("Inventory full!"); } </pre> Here, the vector grows as the player collects items, and the code checks if the inventory is full. Another example is a high-score list: <pre> let mut scores = vec![100, 200, 150]; scores.sort(); // Sort in ascending order println!("Top score: {}", scores.last().unwrap()); </pre> Vectors make it easy to sort, filter, or manipulate lists dynamically. In a server log, you might store incoming requests: <pre> let mut requests = Vec::new(); requests.push("GET /home"); requests.push("POST /login"); for req in requests.iter().rev() { println!("Processing request: {}", req); } </pre> These examples show how vectors adapt to changing data, unlike arrays, which stay fixed. But to use vectors effectively, you need to follow some best practices. Best Practices for Using Vectors * To make vectors work smoothly in your code, keep these tips in mind. Pre-allocate capacity with Vec::with_capacity if you know the approximate size to avoid frequent reallocations, which can slow things down. For example: let mut big_list: Vec<i32> = Vec::with_capacity(1000); * Use get instead of direct indexing when accessing elements to avoid panics, especially with user input. * When iterating, decide whether you need ownership, borrowing (&vec), or mutable borrowing (&mut vec) based on your needs. Also, consider draining or clearing a vector instead of creating a new one if you’re reusing it: inventory.clear(); // Empty the vector, keep the capacity * Finally, if you’re passing vectors between functions, passing a reference (&Vec<T>) is often more efficient than cloning the whole vector. These habits keep your code fast and safe. Speaking of safety, let’s talk about some common pitfalls to avoid. Common Pitfalls and How to Avoid Them Vectors are forgiving, but there are a few traps to watch out for. Indexing out of bounds is a big one: let v = vec![1, 2, 3]; println!("{}", v[10]); // Panic! Out of bounds Use get or check len first: <pre> if v.len() > 10 { println!("{}", v[10]); } else { println!("Index too high!"); } </pre> Another mistake is forgetting to make a vector mutable when you need to modify it: <pre> let v = vec![1, 2, 3]; v.push(4); // Error: v is not mutable </pre> Always add mut when declaring a vector you plan to change. Also, avoid unnecessary cloning of large vectors, as it can be slow, use references or slices instead. Finally, don’t confuse vectors with arrays when planning your data structure. If the size is fixed and small, an array might be simpler and faster. Read the full article here: https://medium.com/rustaceans/vectors-9d14cbaa693f
Summary:
Please note that all contributions to JOHNWICK may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
JOHNWICK:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
Vectors
Add topic