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
Iterators
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 playing with vectors, and enums the last two days, itâs time to look in on Rustâs iterators -a feature that makes working with collections feel like a breeze. Iterators are like a conveyor belt in a factory, delivering items one by one for your code to process, without you needing to micromanage the details. Theyâre flexible, efficient, and pack a punch for real-world tasks. In this guide, weâll walk through what iterators are, how to use them, and how they shine in practical scenarios like processing game scores or filtering server logs. Letâs get the conveyor belt rolling! What Are Iterators? In Rust, an iterator is anything that can produce a sequence of items one at a time. Think of it as a playlist for your data, you hit ânextâ to get the next song, or in this case, the next item. Iterators work with collections like vectors, arrays, or even custom types, and theyâre designed to be lazy, meaning they only compute values when you ask for them. This laziness saves memory and CPU, especially for large datasets. You get an iterator from a collection using methods like iter(), into_iter(), or iter_mut(), like this: let scores = vec![100, 200, 300]; for score in scores.iter() { println!("Score: {}", score); } Here, scores.iter() gives you an iterator that borrows each element, printing 100, 200, 300. Iterators are everywhere in Rust, and understanding their flavors is important to using them well. Letâs see how theyâre created and what makes them tick. Creating Iterators Rust gives us a few ways to create iterators, depending on how you want to interact with your data. Letâs use a real-world example: a game leaderboard with player scores. Suppose you have a vector of scores: let leaderboard = vec![500, 300, 450]; You can create iterators in three main ways: <pre> * iter(): Borrows each element immutably, great for reading data without changing it. for &score in leaderboard.iter() { println!("Player scored: {}", score); } * into_iter(): Takes ownership of the collection, moving its elements. Use this when youâre done with the original vector. let owned: Vec<i32> = leaderboard.into_iter().collect(); * iter_mut(): Borrows elements mutably, letting you modify them in place. let mut leaderboard = vec![500, 300, 450]; for score in leaderboard.iter_mut() { *score += 50; // Boost each score } </pre> Each method fits a different scenario, reading, moving, or modifying. You can also create iterators from scratch, like 0..5 for a range of numbers. Now that we know how to get iterators, letâs see what we can do with them. Common Iterator Methods Iterators come with a toolbox of methods that let you transform, filter, or combine data in clever ways. These methods are chainable, meaning you can string them together like a pipeline. Letâs say youâre running a gaming tournament and need to process scores. Hereâs a taste of what iterators can do: <pre> let scores = vec![100, 250, 75, 300, 150]; let total: i32 = scores.iter() .filter(|&&score| score > 100) // Keep scores above 100 .map(|&score| score + 10) // Add 10-point bonus .sum(); // Add them up println!("Total bonus scores: {}", total); // Prints 560 (260 + 310) </pre> * filter: Keeps only items that match a condition, like scores above 100. * map: Transforms each item, here adding a 10-point bonus. * sum: Adds all items together, perfect for totaling scores. Other handy methods include: * take(n): Grabs the first n items, useful for limiting output. * skip(n): Ignores the first n items, great for pagination. * collect: Turns an iterator back into a collection, like a Vec. These methods make iterators useful for processing data efficiently. Letâs see how they work. Iterators in Real-World Scenarios Iterators shine in practical tasks where you need to process data cleanly. Imagine youâre building a game server that logs player actions, and you want to analyze them. Hereâs a log of actions: <pre> let actions = vec!["jump", "attack", "jump", "heal", "attack"]; let jump_count: i32 = actions.iter() .filter(|&&action| action == "jump") .count() as i32; println!("Players jumped {} times", jump_count); // Prints 2 </pre> This counts how many times players jumped, using filter and count. Now, suppose youâre running a coffee shop app and need to process orders: <pre> let orders = vec![2.50, 3.75, 0.0, 4.25, 2.50]; let valid_total: f32 = orders.into_iter() .filter(|&price| price > 0.0) // Skip invalid orders .map(|price| price * 1.1) // Add 10% tax .sum(); println!("Total with tax: ${:.2}", valid_total); // Prints $9.35 </pre> Here, into_iter consumes the vector, filter removes invalid orders, map adds tax, and sum calculates the total. Iterators make this code concise and readable. Another example: generating a leaderboardâs top 3 scores: let mut scores = vec![500, 300, 450, 600, 200]; scores.sort_by(|a, b| b.cmp(a)); // Sort descending let top_three: Vec<i32> = scores.into_iter().take(3).collect(); println!("Top scores: {:?}", top_three); // Prints [600, 500, 450] These examples show how iterators handle real tasks with minimal fuss. But to use them well, you need to follow some best practices. Best Practices for Using Iterators To make iterators work smoothly, you need to keep a few tips in mind. * Choose the right iterator method for your needs i.e only use iter() for borrowing, into_iter() when youâre okay losing the collection, and iter_mut() for in-place changes. * Chain methods thoughtfully to avoid unnecessary work, filter first to reduce the dataset before mapping or summing. For example: let valid_scores: i32 = scores.iter() .filter(|&&score| score > 0) // Filter first .map(|&score| score * 2) // Then transform .sum(); * If youâre collecting results, specify the type explicitly (e.g., Vec<i32>) to help Rustâs type inference. * Also, be mindful of iterator laziness, i.e methods like map or filter donât run until you consume the iterator with something like collect or for. * Finally, use ranges (0..n) for simple sequences to avoid creating vectors unnecessarily. Common Pitfalls and How to Avoid Them Iterators are great, but they can trip you up. One common mistake is forgetting that into_iter() consumes the collection, making it unusable afterward. let v = vec![1, 2, 3]; let sum: i32 = v.into_iter().sum(); println!("Vector: {:?}", v); // Error: v was moved! Use iter() instead if you need the vector later. Another pitfall is infinite iterators, like the cycle() from our quiz. Without take(), this loops forever: let infinite = (0..3).cycle(); // 0, 1, 2, 0, 1, 2, ... Always pair cycle() with take(n). Also, avoid redundant cloning of large collections, pass references to iter() instead. Finally, watch out for empty iterators when using methods like sum() or max(), which might return unexpected types or None: let empty: Vec<i32> = vec![]; let max = empty.iter().max(); // Returns None Check for empty collections before calling such methods. Read the full article here: https://medium.com/rustaceans/iterators-e9199987811f
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
Iterators
Add topic