← Back to Rust Course | Chapter 14: Closures, Iterators & Async | Lesson 2 of 6

Iterator Trait का उपयोग

Iterator trait वह recipe है जो Rust में हर list-walker follow करता है: इसे सिर्फ यह जानना है कि अगला item कैसे वापस देना है।
Syntax
rust
impl Iterator for Name {
    type Item = Type;

    fn next(&mut self) -> Option<Self::Item> {
        // body
    }
}

Calling next Manually

हर iterator एक next() method प्रदान करता है जो ज़्यादा elements होने पर Some(item) return करता है, और खत्म हो जाने पर None। एक for loop बस hood के नीचे बार-बार next() call करना है।

उदाहरण: Calling next Manually

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare a mutable variable `iter`, initialized to `vec![1, 2, 3].into_iter()`
    let mut iter = vec![1, 2, 3].into_iter();
    // Print "{:?}" to the console, substituting in `iter.next()` (with a trailing newline)
    println!("{:?}", iter.next());
    // Print "{:?}" to the console, substituting in `iter.next()` (with a trailing newline)
    println!("{:?}", iter.next());
    // Print "{:?}" to the console, substituting in `iter.next()` (with a trailing newline)
    println!("{:?}", iter.next());
    // Print "{:?}" to the console, substituting in `iter.next()` (with a trailing newline)
    println!("{:?}", iter.next());
}

Implementing a Custom Iterator

अपने खुद के type के लिए Iterator implement करने में सिर्फ next() define करना चाहिए; associated Item type बताता है कि iterator किस तरह की value produce करता है।

उदाहरण: Implementing a Custom Iterator

markup
// Define a struct `Countdown` to group related fields together
struct Countdown(u32);

// Implement the `Iterator` trait for `Countdown`
impl Iterator for Countdown {
    type Item = u32;
    // Define the function `next` taking `self` and returning a `Option<u32>`
    fn next(&mut self) -> Option<u32> {
        // Check whether `self.0 == 0`
        if self.0 == 0 {
            None
        // Otherwise, run this branch
        } else {
            self.0 -= 1;
            Some(self.0 + 1)
        }
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `countdown`, set to `Countdown(3)`
    let countdown = Countdown(3);
    // Loop over `countdown`, binding each item to `n`
    for n in countdown {
        // Print "{}" to the console, substituting in `n` (with a trailing newline)
        println!("{}", n);
    }
}

Free Adapter Methods from Iterator

एक बार कोई type next() define करके Iterator implement कर ले, यह अपने आप कई built-in adapter methods तक access पाता है, जैसे .sum(), बिना किसी extra काम के।

उदाहरण: Free Adapter Methods from Iterator

markup
// Define a struct `Countdown` to group related fields together
struct Countdown(u32);

// Implement the `Iterator` trait for `Countdown`
impl Iterator for Countdown {
    type Item = u32;
    // Define the function `next` taking `self` and returning a `Option<u32>`
    fn next(&mut self) -> Option<u32> {
        // Check whether `self.0 == 0`
        if self.0 == 0 {
            None
        // Otherwise, run this branch
        } else {
            self.0 -= 1;
            Some(self.0 + 1)
        }
    }
}

// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `total` (an unsigned integer), set to `Countdown(4).sum()`
    let total: u32 = Countdown(4).sum();
    // Print "Sum: {}" to the console, substituting in `total` (with a trailing newline)
    println!("Sum: {}", total);
}

Iterators Are Lazy

.map() जैसे Iterator adapters अपना closure तुरंत नहीं चलाते -- वे एक pipeline description बनाते हैं जो सिर्फ तब execute होता है जब कुछ iterator consume करे, जैसे .collect() या एक for loop।

उदाहरण: Iterators Are Lazy

markup
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `numbers`, set to `vec![1, 2, 3]`
    let numbers = vec![1, 2, 3];
    let lazy_iter = numbers.iter().map(|n| {
        // Print "Processing {}" to the console, substituting in `n` (with a trailing newline)
        println!("Processing {}", n);
        n * 2
    });
    // Declare an immutable variable `result` (a `Vec<i32>`), set to `lazy_iter.collect()`
    let result: Vec<i32> = lazy_iter.collect();
    // Print "{:?}" to the console, substituting in `result` (with a trailing newline)
    println!("{:?}", result);
}
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. #}
आम गलतियां
  1. यह भूल जाना कि .next() एक Option<Item> return करता है, iterator खत्म होने का signal देने के लिए None उपयोग करते हुए।
  2. यह मान लेना कि iterators eager हैं -- .map() जैसे ज़्यादातर iterator adapters lazy हैं और consume होने तक नहीं चलते।
  3. Iterator implement करना लेकिन यह भूल जाना कि इसे सिर्फ next() define करना चाहिए; बाकी हर method की इसके ऊपर एक default implementation है।
चैप्टर सारांश
  • Iterator trait को सिर्फ एक method चाहिए, next(&mut self) -> Option<Self::Item>।
  • .next() को बार-बार call करना sequence खत्म होने तक Some(item) yield करता है, फिर None return करता है।
  • किसी custom type के लिए Iterator implement करना अपने आप .map() और .filter() जैसे दर्जनों adapter methods unlock करता है।
  • Iterators lazy हैं: adapters एक pipeline बनाते हैं जो सिर्फ consume होने पर असल में चलता है, जैसे .collect() या एक for loop से।
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 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.