Macro iterate::iterate [−][src]
iterate!() { /* proc-macro */ }
Expand description
Create an iterator on the fly
The iterate
macro creates an iterator on the fly:
use iterate::iterate; let mut iterator = iterate![1, 2, 3]; assert_eq!(iterator.next(), Some(1)); assert_eq!(iterator.next(), Some(2)); assert_eq!(iterator.next(), Some(3)); assert_eq!(iterator.next(), None);
The iterator lazily evaluates each of its arguments, one at a time:
use std::cell::Cell; use iterate::iterate; let cell = Cell::new(0); let cell = &cell; let mut iterator = iterate![ {cell.set(cell.get() + 1); 1}, {cell.set(cell.get() + 1); 2}, {cell.set(cell.get() + 1); 3}, ]; assert_eq!(cell.get(), 0); assert_eq!(iterator.next(), Some(1)); assert_eq!(cell.get(), 1); assert_eq!(iterator.next(), Some(2)); assert_eq!(cell.get(), 2); assert_eq!(iterator.next(), Some(3)); assert_eq!(cell.get(), 3); assert_eq!(iterator.next(), None);
Most usefully, iterate
can capture any other IntoIterator
type and
iterate over it, by prefixing the value with ..
:
use iterate::iterate; let range = 0..5; let vec = vec![4, 1, 2, 3]; // Iterate captures its arguments by move, and evaluates them lazily, so we // need to ensure that the vec is captured by reference let vec = &vec; let iterator = iterate![ 1, ..range, ..vec.iter().copied(), 10 ]; let result: Vec<i32> = iterator.collect(); assert_eq!(result, [ 1, 0, 1, 2, 3, 4, 4, 1, 2, 3, 10, ])
Eager and Lazy evaluation
iterate
tries to be smart about when it evaluates its arguments eagerly vs
lazily. In general it tries to evaluate them lazily, but in cases where it’s
sure there will be no side effects, it evaluates ..iter
arguments eagerly.
It does this so that it can provide a more reliable size_hint
.