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 数据结构
5,638 每月下载量
用于 8 个 crate (7 直接)
155KB
2.5K SLoC
通过构建保证的集合
标准集合的非空变体。
非空可以是一个强大的保证。如果你的主要用途是将 Vec
作为 Iterator
使用,那么你可能不需要区分是否为空。但是确实存在这样的情况:作为函数参数接收到的 Vec
需要是非空的,否则你的函数无法继续执行。同样,也有时候你需要向调用用户返回的 Vec
承诺它实际上包含了一些内容。
使用 NEVec
,你将不再需要不断检查 is_empty()
或在继续之前进行模式匹配,或者无法执行时引发错误。因此,代码、类型签名和逻辑都变得更加简洁。
考虑一下,与 Vec
不同,NEVec::first
和 NEVec::last
不返回在 Option
中;它们总是成功的。
与 NEVec
一起的是它的堂兄弟 NESlice
、NEMap
和 NESet
,所有这些都保证至少包含一个项目。
示例
构建这些非空集合的最简单方法是通过它们的宏: 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
注意事项
由于 NEVec
、NEMap
和 NESet
必须至少有一个元素,因此无法为它们实现 FromIterator
特性。在一般情况下,我们无法知道任何给定的标准库 Iterator
是否实际包含某些内容。
功能
serde
:支持serde
。indexmap
:支持非空IndexMap
依赖关系
~0–330KB