Iterator Trait का उपयोग
Iterator trait वह recipe है जो Rust में हर list-walker follow करता है: इसे सिर्फ यह जानना है कि अगला item कैसे वापस देना है।In this page:
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
// 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());
}
Login to try C/C++/Java/PHP code in the editor
Implementing a Custom Iterator
अपने खुद के type के लिए Iterator implement करने में सिर्फ next() define करना चाहिए; associated Item type बताता है कि iterator किस तरह की value produce करता है।
उदाहरण: Implementing a Custom Iterator
// 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);
}
}
Login to try C/C++/Java/PHP code in the editor
Free Adapter Methods from Iterator
एक बार कोई type next() define करके Iterator implement कर ले, यह अपने आप कई built-in adapter methods तक access पाता है, जैसे .sum(), बिना किसी extra काम के।
उदाहरण: Free Adapter Methods from Iterator
// 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);
}
Login to try C/C++/Java/PHP code in the editor
Iterators Are Lazy
.map() जैसे Iterator adapters अपना closure तुरंत नहीं चलाते -- वे एक pipeline description बनाते हैं जो सिर्फ तब execute होता है जब कुछ iterator consume करे, जैसे .collect() या एक for loop।
उदाहरण: Iterators Are Lazy
// 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);
}
Login to try C/C++/Java/PHP code in the editor
- यह भूल जाना कि
.next()एकOption<Item>return करता है, iterator खत्म होने का signal देने के लिएNoneउपयोग करते हुए। - यह मान लेना कि iterators eager हैं --
.map()जैसे ज़्यादातर iterator adapters lazy हैं और consume होने तक नहीं चलते। Iteratorimplement करना लेकिन यह भूल जाना कि इसे सिर्फnext()define करना चाहिए; बाकी हर method की इसके ऊपर एक default implementation है।
Iteratortrait को सिर्फ एक method चाहिए,next(&mut self) -> Option<Self::Item>।.next()को बार-बार call करना sequence खत्म होने तकSome(item)yield करता है, फिरNonereturn करता है।- किसी custom type के लिए
Iteratorimplement करना अपने आप.map()और.filter()जैसे दर्जनों adapter methods unlock करता है। - Iterators lazy हैं: adapters एक pipeline बनाते हैं जो सिर्फ consume होने पर असल में चलता है, जैसे
.collect()या एकforloop से।
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: