← Back to Rust Course | Chapter 3: Control Flow | Lesson 4 of 7

for Loops and Ranges

A for loop lets you walk through a list of numbers or items one by one, automatically, without any bookkeeping.
Syntax
rust
for item in collection {
    // body
}

for i in start..end {
    // end is exclusive
}

for i in start..=end {
    // end is inclusive
}

Iterating a Range

A range like 0..5 produces the sequence 0, 1, 2, 3, 4 -- note the upper bound is exclusive. A for loop can iterate directly over such a range without any manual counter.

Example: Iterating a Range

markup
// Entry point: execution of the program starts here
fn main() {
    // Loop over `0..5`, binding each item to `i`
    for i in 0..5 {
        // Print "i = {}" to the console, substituting in `i` (with a trailing newline)
        println!("i = {}", i);
    }
}

Inclusive Ranges

Adding an equals sign, 0..=5, creates an inclusive range that includes the final number, producing 0 through 5. Use this when you want the endpoint included.

Example: Inclusive Ranges

markup
// Entry point: execution of the program starts here
fn main() {
    // Loop over `1..=3`, binding each item to `i`
    for i in 1..=3 {
        // Print "Count: {}" to the console, substituting in `i` (with a trailing newline)
        println!("Count: {}", i);
    }
}

Iterating a Collection

for loops can iterate directly over the elements of an array or other collection, giving you each value in turn without ever touching an index.

Example: Iterating a Collection

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `fruits`, set to `["apple", "banana", "cherry"]`
    let fruits = ["apple", "banana", "cherry"];
    // Loop over `fruits.iter()`, binding each item to `fruit`
    for fruit in fruits.iter() {
        // Print "Fruit: {}" to the console, substituting in `fruit` (with a trailing newline)
        println!("Fruit: {}", fruit);
    }
}

Using enumerate for Index and Value

When you need both the position and the value while iterating, .enumerate() wraps an iterator to yield (index, value) pairs, avoiding manual counters entirely.

Example: Using enumerate for Index and Value

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `colors`, set to `["red", "green", "blue"]`
    let colors = ["red", "green", "blue"];
    // Loop over `colors.iter().enumerate()`, binding each item to `(index, color)`
    for (index, color) in colors.iter().enumerate() {
        // Print "{}: {}" to the console, substituting in `index, color` (with a trailing newline)
        println!("{}: {}", index, color);
    }
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Writing for i in 0..n when you actually need to include n, forgetting that .. is exclusive of the upper bound.
  2. Manually managing an index variable and a while loop instead of using Rust's safer and more idiomatic for loop.
  3. Trying to modify a collection's length while iterating over it directly by value, which the borrow checker will reject.
Chapter Summary
  • for item in collection iterates over every element of a collection or range automatically.
  • 0..5 is an exclusive range (0 to 4); 0..=5 is inclusive (0 to 5).
  • for loops are preferred over manual indexing because they eliminate off-by-one errors.
  • .enumerate() can be combined with for to get both the index and the value.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.