6个版本 (3个重大更新)
0.4.1 | 2024年4月9日 |
---|---|
0.4.0 | 2023年5月9日 |
0.3.0 | 2022年10月18日 |
0.2.0 | 2022年8月13日 |
0.1.1 | 2021年7月3日 |
#180 in 数据结构
1,166 每月下载量
用于 3 crates
29KB
439 行
validated
Result
和 Either
的累积兄弟。
Validated
类型具有特殊的 FromIterator
实例,这些实例能够报告序列中的所有错误,而不仅仅是第一个。
动机
我们可能会将 Iterator::collect
视为将某些链式迭代的结果合并到具体容器中,例如 Vec
。
let v = vec![1,2,3];
assert_eq!(vec![2,4,6], v.into_iter().map(|n| n * 2).collect::<Vec<u32>>());
但 collect
不限于这一点;只要它实现了 FromIterator
,它就可以用于将结果“折叠”到任何你喜欢的类型中。考虑以下 impl
的效果 Result
let v: Vec<u32> = vec![1, 2, 3];
let r: Result<Vec<u32>, &str> = v
.into_iter()
.map(|n| if n % 2 == 0 { Err("Oh no!") } else { Ok(n * 2) })
.collect();
assert_eq!(Err("Oh no!"), r);
Result
已经“交织”并拉回。关键的是,这个 collect
调用是短路;对于 3
,n * 2
从未调用,因为 map
在 2
处“失败”。这在我们需要一系列IO操作都成功,并在任何错误发生时取消剩余操作时很有用。
但如果我们不想短路怎么办?如果我们想报告发生的所有错误怎么办?
累积错误和 Validated
考虑三种情况,我们希望报告所有错误,而不仅仅是第一个错误。
- 表单输入验证。
- 类型检查。
- 并发I/O。
在第一种情况下,如果用户犯了几个错误,最好一次性报告所有错误,以便他们可以在一次遍历中完成更正。
在第二种情况下,仅知道第一个检测到的类型错误可能实际上并不是问题的真正来源。我们需要报告所有故障,以便我们能够做出最好的修复决定。
在第三种情况下,在检测到单个故障时停止整个并发作业可能并不合适。您可能更希望所有作业都能完成,然后在结束时收集错误。
Validated
类型适用于这些用例;它是一个“累积的 Result
”。
use validated::Validated::{self, Good, Fail};
use nonempty_collections::*;
let v = vec![Good(1), Validated::fail("No!"), Good(3), Validated::fail("Ack!")];
let r: Validated<Vec<u32>, &str> = Fail(nev!["No!", "Ack!"]);
assert_eq!(r, v.into_iter().collect());
非空向量(NEVec
)的使用
本着“使非法状态无法表示”的精神,Validated
的 Fail
变体包含一个 NEVec
,一个非空 Vec
。 NEVec
可以做所有 Vec
能做的事情,还有一些额外的优势。在这个 crate 中,这种表示禁止了其他情况下没有意义的 Fail(vec![])
。
换句话说,如果您有一个 Validated<T, E>
,那么您要么有具体的 T
,要么有至少一个 E
。
特性
rayon
:为Validated
启用FromParallelIterator
实例。
资源
依赖关系
~150–415KB