#iterator #cache #memoization #repeat #restart #no-alloc

no-std reiterator

仅计算每个元素一次的懒加载可重复缓存迭代器

5个版本

0.3.0 2023年7月3日
0.1.3 2023年7月2日
0.1.2 2023年7月2日
0.1.1 2023年7月2日
0.1.0 2023年7月1日

数学类中排名第893


3个Crate中使用(通过breadth-first-zip

MPL-2.0许可

26KB
419

Reiterator

你有没有那种朋友,总是反复说同样的事情,但你只真正听了一次?也许他们甚至有一套故事,你只需要听一次就足够了?

这个crate就是这样。

什么意思?

这个no_std crate接受一个迭代器并缓存其输出,允许你访问任何引用透明迭代器调用的不可变引用。可以回滚它或将它向前设置十个元素,但只有在你请求的时候才会这么做。Rust的懒加载评估在即时风格中的一点点味道。此外,它还会返回值的索引,但有一些内置的与map兼容的迷你函数,可以仅获取值或索引。

use reiterator::{Reiterate, indexed::Indexed};

let mut iter = vec!['a', 'b', 'c'].reiterate(); // None of the values are computed or cached until...

// You can drive it like a normal `Iterator`:
assert_eq!(iter.next(), Some(Indexed { index: 0, value: &'a' })); // here: only the first one, whose cache is referenced.
assert_eq!(iter.next(), Some(Indexed { index: 1, value: &'b' })); // Cooked up the second value on demand.
assert_eq!(iter.next(), Some(Indexed { index: 2, value: &'c' }));
assert_eq!(iter.next(), None); // Out of bounds!

// Note that we literally return the same memory addresses as before:
iter.restart();
assert_eq!(iter.next(), Some(Indexed { index: 0, value: &'a' }));
assert_eq!(iter.next(), Some(Indexed { index: 1, value: &'b' }));

// Start from anywhere:
iter.index.set(1);
assert_eq!(iter.next(), Some(Indexed { index: 1, value: &'b' }));
assert_eq!(iter.next(), Some(Indexed { index: 2, value: &'c' }));

// Or hop around at will, just as quickly (if not faster):
assert_eq!(iter.at(1), Some(&'b'));
assert_eq!(iter.at(2), Some(&'c'));
assert_eq!(iter.at(3), None);

只为做这件事而创建一个整个crate?

是的,我知道。这很简单。但生命周期和边缘情况很难正确处理,也很容易忽略。

把它想象成把将来会经历的所有痛苦都转移给我,这样世界上就不需要那么多人承受痛苦了。实用主义,真的。

无运行时依赖