Course contentsShow
← Rust
Lesson 948 of 1,9108. Collections and Iterator PipelinesFree lesson

Lazy Evaluation Semantics

You will be able to reason about when iterator pipelines actually execute versus when they are defined.

In this lesson, you will learn how to distinguish between the definition of an iterator pipeline and the moment it actually performs work.

In Rust, iterators are lazy. When you chain methods like .map(), .filter(), or .take(), you aren't actually transforming data or iterating through a collection. Instead, you are constructing a state machine—a complex, nested data structure that describes how to process the data once you finally ask for it.

The Pipeline vs. The Execution

Consider this code:

let numbers = vec![1, 2, 3, 4, 5];

let pipeline = numbers.iter()
    .map(|x| {
        println!("Mapping {}", x);
        x * 2
    })
    .filter(|&x| x > 5);

If you run this code, nothing happens. No values are printed, and no multiplication occurs. The pipeline variable simply holds an iterator object that knows the rules for the transformation. The pipeline is only "executed" when you invoke a consuming adapter—a method that iterates through the sequence to produce a final result, such as .collect(), .for_each(), or .count().

// Now the work begins:
let results: Vec<i32> = pipeline.collect(); 
// Output: 
// Mapping 1
// Mapping 2
// ...

Why Does This Matter?

This design is a powerful optimization strategy. Because Rust waits until the last possible moment to evaluate the chain, it can perform "loop fusion." Instead of creating an intermediate vector for every step (which would allocate memory unnecessarily), Rust executes the entire pipeline for each element individually before moving to the next one.

By deferring execution, you avoid building temporary collections and allow the compiler to inline your closures directly into the iteration logic. You aren't just calling functions; you are building a custom execution plan that the compiler optimizes into a single, efficient loop.

Key Takeaway: Iterator pipelines are merely recipes; they remain dormant until a consuming method forces the evaluation of the underlying data.