iter
import std::core::iter; — in the prelude · source
Iterator
type trait Iterator {
type Item;
next(mut &this) -> Option<This::Item>;
count(mut &this) -> u64;
fold<Acc>(mut &this, initial: Acc, f: (Acc, This::Item) -> Acc) -> Acc;
for_each(mut &this, f: (This::Item) -> void) -> void;
take(this, n: u64) -> TakeIter<This>;
skip(this, n: u64) -> SkipIter<This>;
map<B>(this, f: (This::Item) -> B) -> MapIter<This, B>;
filter(this, pred: (This::Item) -> boolean) -> FilterIter<This>;
chain<J>(this, other: J) -> ChainIter<This, J>;
enumerate(this) -> EnumerateIter<This>;
zip<J>(this, other: J) -> ZipIter<This, J>;
any(mut &this, pred: (This::Item) -> boolean) -> boolean;
all(mut &this, pred: (This::Item) -> boolean) -> boolean;
find(mut &this, pred: (This::Item) -> boolean) -> Option<This::Item>;
min(mut &this) -> Option<This::Item>
where This::Item: Ord;
max(mut &this) -> Option<This::Item>
where This::Item: Ord;
}
Iterator has exactly one required method — next — and everything else is derived from it. for (x in seq) drives the scrutinee through this trait, so anything that implements it works in a for loop. Item is an associated type; implement Iterator<T> for X is positional sugar for binding it.
type struct Counter { n: i32; }
implement trait Iterator<i32> for struct Counter {
next(mut &this) -> Option<i32> {
if (this.n >= 5) { return Option<i32>::None; }
this.n = this.n + 1;
return Option<i32>::Some(this.n);
}
}
mut c: Counter = Counter { n: 0 };
for (v in c.take(3)) { println(f"{v}"); }
Lazy adapters
Each of these returns a wrapper that is itself an Iterator, so they compose. Nothing is computed until something consumes the chain.
| Adapter | Yields |
|---|---|
take(n) | At most the first n elements. |
skip(n) | Everything after the first n. |
map<B>(f) | f applied to each element. |
filter(pred) | Only the elements where pred holds. |
chain<J>(other) | All of this, then all of other (same Item type). |
enumerate() | Pair<u64, Item> — .first is the 0-based index. |
zip<J>(other) | Pair<Item, B>, stopping when either side runs out. |
f and pred must be non-capturing — a plain function or a non-capturing lambda.
enumerate and zip yield Pair rather than a tuple because Cryo has no heterogeneous tuple literal.
The adapter types
type struct TakeIter<I> {
inner: I;
remaining: u64;
static new(inner: I, n: u64) -> TakeIter<I>;
}
type struct SkipIter<I> {
inner: I;
remaining: u64;
static new(inner: I, n: u64) -> SkipIter<I>;
}
type struct MapIter<I, O> {
inner: I;
f: (I::Item) -> O;
static new(inner: I, f: (I::Item) -> O) -> MapIter<I, O>;
}
type struct FilterIter<I> {
inner: I;
pred: (I::Item) -> boolean;
static new(inner: I, pred: (I::Item) -> boolean) -> FilterIter<I>;
}
type struct ChainIter<I, J> {
first: I;
second: J;
first_done: boolean;
static new(first: I, second: J) -> ChainIter<I, J>;
}
type struct EnumerateIter<I> {
inner: I;
index: u64;
static new(inner: I) -> EnumerateIter<I>;
}
type struct ZipIter<I, J> {
first: I;
second: J;
static new(first: I, second: J) -> ZipIter<I, J>;
}
The wrappers the adapters return are public structs, so you can name one in a signature when the opaque implement Iterator<T> is not enough. Each is an Iterator in turn; their impls are listed under Implementors.
Eager consumers
| Consumer | Returns |
|---|---|
count() | u64 — walks the iterator to count, consuming it. |
fold<Acc>(initial, f) | Acc |
for_each(f) | void |
any(pred) / all(pred) | boolean — both short-circuit. |
find(pred) | Option<Item> |
min() / max() (where Item: Ord) | Option<Item> |
On ties min keeps the first minimal element and max keeps the last maximal one, matching the conventional behaviour.
The adapters resolve on any concrete Iterator receiver, including your own structs. Re-adapting a local whose type is the opaque implement Iterator<T> works when its initialiser is a concrete constructor (mut it: implement Iterator<i32> = Range<i32>::new(0, 10); it.take(3)); a local initialised from a producer that itself returns an opaque iterator is still restricted, so chain directly off the source in that case.
Implementors
Every iterator in the library, including the adapters above and the by-reference cursors the containers hand out:
implement<I, A> trait Iterator<A> for struct TakeIter<I>
where I: Iterator<A>
implement<I, A> trait Iterator<A> for struct SkipIter<I>
where I: Iterator<A>
implement<I, O> trait Iterator<O> for struct MapIter<I, O>
where I: Iterator
implement<I> trait Iterator<I::Item> for struct FilterIter<I>
where I: Iterator
implement<I, J, A> trait Iterator<A> for struct ChainIter<I, J>
where I: Iterator<A>, J: Iterator<A>
implement<I> trait Iterator<Pair<u64, I::Item>> for struct EnumerateIter<I>
where I: Iterator
implement<I, J, A, O> trait Iterator<Pair<A, O>> for struct ZipIter<I, J>
where I: Iterator<A>, J: Iterator<O>
implement<T> trait Iterator<T*> for struct RefIter<T> // std::collections::array
implement<I, T> trait Iterator<T> for struct CopiedIter<I>
where I: Iterator<T*>, T: Copy // std::collections::array
implement<I, T> trait Iterator<T> for struct ClonedIter<I>
where I: Iterator<T*>, T: Clone // std::collections::array
implement<K, V> trait Iterator<Pair<K, V>> for struct HashMapIter<K, V>
where K: Copy, V: Copy // std::collections::hashmap
implement<K, V> trait Iterator<K> for struct KeysIter<K, V> // std::collections::hashmap
implement<K, V> trait Iterator<V> for struct ValuesIter<K, V> // std::collections::hashmap
implement<K, V> trait Iterator<Pair<K*, V*>> for struct EntriesRefIter<K, V> // std::collections::hashmap
implement<K, V> trait Iterator<K*> for struct KeysRefIter<K, V> // std::collections::hashmap
implement<K, V> trait Iterator<V*> for struct ValuesRefIter<K, V> // std::collections::hashmap
implement<T> trait Iterator<T> for struct HashSetIter<T>
where T: Copy // std::collections::hashset
implement<T> trait Iterator<T*> for struct HashSetRefIter<T> // std::collections::hashset
implement trait Iterator<Str> for struct SplitIter // std::collections::str
implement trait Iterator<u32> for struct Chars // std::collections::str
implement trait Iterator<Pair<u64, u32>> for struct CharIndices // std::collections::str
implement<T> trait Iterator<T> for struct Range<T>
where T: Step // std::core::ops
implement<T> trait Iterator<T> for struct RangeInclusive<T>
where T: Step // std::core::ops
implement<T> trait Iterator<T> for struct SliceIter<T> // std::core::slice
implement trait Iterator<DirEntry> for struct ReadDir // std::fs::dir