1 个不稳定版本
0.1.0 | 2024年2月24日 |
---|
#10 在 #iterators
26KB
483 行
inf_vec
这是一个Rust包,提供了 InfVec
类型,这是一个懒加载的无限 Vec
类型的数据结构。
有关用法信息,请参阅文档。
lib.rs
:
此包提供了 InfVec
,一个懒加载的无限 Vec
类型的数据结构。
InfVec<T, I>
包含无限多个类型为 T
的值。它可以像 Vec
一样迭代和索引。元素由一个类型为 I
的迭代器按需生成,该迭代器在创建 InfVec
时指定。元素可以通过索引访问,并且可以修改。
如果迭代器不是无限的,则对 InfVec
的操作可能会崩溃。
InfVec
目前是不变的,而不是协变的,如果你在意的话。
InfVec
是线程安全的,因此您可以将其放在 static
变量中。
尽管名称如此,InfVec
并不真正像 Vec
一样连续存储元素。相反,它将元素存储在64个元素的块中。这样我们就可以发放元素的引用,而不会因为缓存中添加了更多元素而使它们失效。
如果您不想指定迭代器类型作为类型参数,您可以使用 InfVecBoxed
或 InfVecOwned
类型别名。
示例
修改 InfVec
use inf_vec::InfVec;
let mut inf_vec = InfVec::new(0..);
assert_eq!(
inf_vec.iter().take(10).copied().collect::<Vec<_>>(),
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
);
inf_vec[3] = 100;
assert_eq!(
inf_vec.iter().take(10).copied().collect::<Vec<_>>(),
[0, 1, 2, 100, 4, 5, 6, 7, 8, 9]
);
重用静态 InfVec
use inf_vec::{InfVec, InfVecOwned, IteratorInfExt};
use once_cell::sync::Lazy;
// Note that each element will only ever be produced once.
static EVENS: Lazy<InfVecOwned<i32>> =
Lazy::new(|| (0..).map(|x| x * 2).collect_inf().boxed());
fn evens_with_property(mut predicate: impl FnMut(i32) -> bool) -> impl Iterator<Item = i32> {
EVENS.iter().copied().filter(move |&x| predicate(x))
}
assert_eq!(
evens_with_property(|x| x % 3 == 0)
.take(5)
.collect::<Vec<_>>(),
[0, 6, 12, 18, 24]
);
assert_eq!(
evens_with_property(|x| x % 5 == 0)
.take(5)
.collect::<Vec<_>>(),
[0, 10, 20, 30, 40]
);
递归 InfVec
use inf_vec::{InfVec, InfVecBoxed};
use std::sync::Arc;
let fibonacci: Arc<InfVecBoxed<i32>> = InfVec::recursive(|fibonacci_ref, i| {
if i < 2 {
1
} else {
fibonacci_ref[i - 1] + fibonacci_ref[i - 2]
}
});
assert_eq!(
fibonacci.iter().take(10).copied().collect::<Vec<_>>(),
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
);