#iterator #infinite #lazy-evaluation #sequence

已删除 inf_vec

一个懒加载的无限 Vec-like 数据结构

1 个不稳定版本

0.1.0 2024年2月24日

#10#iterators

MIT 许可证

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个元素的块中。这样我们就可以发放元素的引用,而不会因为缓存中添加了更多元素而使它们失效。

如果您不想指定迭代器类型作为类型参数,您可以使用 InfVecBoxedInfVecOwned 类型别名。

示例

修改 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]
);

无运行时依赖