#非空 #映射 #集合 #向量

nonempty-collections

通过构建保证非空集合

12 个版本

新增 0.2.8 2024 年 8 月 19 日
0.2.7 2024 年 7 月 22 日
0.2.6 2024 年 6 月 26 日
0.2.3 2024 年 3 月 19 日
0.1.1 2023 年 4 月 8 日

#84 in 数据结构

Download history 471/week @ 2024-05-03 364/week @ 2024-05-10 505/week @ 2024-05-17 663/week @ 2024-05-24 482/week @ 2024-05-31 481/week @ 2024-06-07 548/week @ 2024-06-14 985/week @ 2024-06-21 566/week @ 2024-06-28 880/week @ 2024-07-05 911/week @ 2024-07-12 1126/week @ 2024-07-19 1034/week @ 2024-07-26 1401/week @ 2024-08-02 1578/week @ 2024-08-09 1383/week @ 2024-08-16

5,638 每月下载量
用于 8 个 crate (7 直接)

MIT 许可证

155KB
2.5K SLoC

通过构建保证的集合

标准集合的非空变体。

非空可以是一个强大的保证。如果你的主要用途是将 Vec 作为 Iterator 使用,那么你可能不需要区分是否为空。但是确实存在这样的情况:作为函数参数接收到的 Vec 需要是非空的,否则你的函数无法继续执行。同样,也有时候你需要向调用用户返回的 Vec 承诺它实际上包含了一些内容。

使用 NEVec,你将不再需要不断检查 is_empty() 或在继续之前进行模式匹配,或者无法执行时引发错误。因此,代码、类型签名和逻辑都变得更加简洁。

考虑一下,与 Vec 不同,NEVec::firstNEVec::last 不返回在 Option 中;它们总是成功的。

NEVec 一起的是它的堂兄弟 NESliceNEMapNESet,所有这些都保证至少包含一个项目。

示例

构建这些非空集合的最简单方法是通过它们的宏: nev!nes!nem!

use nonempty_collections::*;

let v: NEVec<u32> = nev![1, 2, 3];
let s: NESet<u32> = nes![1, 2, 2, 3]; // 1 2 3
let m: NEMap<&str, bool> = nem!["a" => true, "b" => false];
assert_eq!(1, v.head);
assert_eq!(3, s.len().get());
assert!(m.get("a").unwrap());

与熟悉的 vec! 宏不同,nev! 和类似的宏至少需要一个元素

use nonempty_collections::nev;

let v = nev![1];

// Doesn't compile!
// let v = nev![];

Vec 类似,您也可以使用 NEVec 以传统方式构建,使用 NEVec::new 或其构造函数

use nonempty_collections::NEVec;

let mut l = NEVec { head: 42, tail: vec![36, 58] };
assert_eq!(l.head, 42);

l.push(9001);
assert_eq!(l.last(), &9001);

如果需要,您可以将它们转换为 Vec 并返回

use nonempty_collections::{NEVec, nev};

let l: NEVec<u32> = nev![42, 36, 58, 9001];
let v: Vec<u32> = l.into();
assert_eq!(v, vec![42, 36, 58, 9001]);

let u: Option<NEVec<u32>> = NEVec::from_vec(v);
assert_eq!(Some(nev![42, 36, 58, 9001]), u);

迭代器

这个库将非空的概念扩展到迭代器,并提供了 NonEmptyIterator 特性。这有一些有趣的结果

  • map 之类的函数会保留非空性。
  • max 之类的函数总是有结果。
  • 非空迭代器链可以被 collect 收集回非空结构。
  • 您可以将许多操作链接起来,而无需再次检查空性。
use nonempty_collections::*;

let v: NEVec<_> = nev![1, 2, 3].into_nonempty_iter().map(|n| n + 1).collect();
assert_eq!(2, v.head);

还可以考虑 IteratorExt::to_nonempty_iter,将任何给定的 Iterator 转换为非空迭代器,如果它包含至少一个项目。

数组

由于固定大小的数组根据定义已经不为空,因此它们没有像 crate::NEVec 这样的特殊包装类型。相反,我们使它们能够以兼容的方式轻松迭代

use nonempty_collections::*;

let a: [u32; 4] = [1, 2, 3, 4];
let v: NEVec<_> = a.into_nonempty_iter().map(|n| n + 1).collect();
assert_eq!(nev![2, 3, 4, 5], v);

有关更多转换,请参阅 NonEmptyArrayExt

注意事项

由于 NEVecNEMapNESet 必须至少有一个元素,因此无法为它们实现 FromIterator 特性。在一般情况下,我们无法知道任何给定的标准库 Iterator 是否实际包含某些内容。

功能

  • serde:支持 serde
  • indexmap:支持非空 IndexMap

依赖关系

~0–330KB