Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust:如何在first Err或None上短路退出迭代器方法链?_Rust_Iterator_Monads_Short Circuiting - Fatal编程技术网

Rust:如何在first Err或None上短路退出迭代器方法链?

Rust:如何在first Err或None上短路退出迭代器方法链?,rust,iterator,monads,short-circuiting,Rust,Iterator,Monads,Short Circuiting,考虑一系列迭代器方法: .iter().a().b().c() 其中a生成类型为Option(或Result)的值。当a产生None(或Err())时,是否有办法让整个链返回None(或Err()) 详细示例 给定函数有效(识别无意义的输入)和接受(一个 任意选择标准): 类型T=u8; 类型ERR=u8; fn有效(x:&T)->结果{ 如果*xbool{ 如果*x>9{panic!(“{}应该被验证器拒绝”)} *x%2==0 } 我想写一个函数 fn计数\u已接受(数据:&[T])->

考虑一系列迭代器方法:

.iter().a().b().c()
其中
a
生成类型为
Option
(或
Result
)的值。当
a
产生
None
(或
Err()
)时,是否有办法让整个链返回
None
(或
Err()

详细示例 给定函数<代码>有效<代码>(识别无意义的输入)和<代码>接受<代码>(一个 任意选择标准):

类型T=u8;
类型ERR=u8;
fn有效(x:&T)->结果{
如果*x<10{Ok(*x)}否则{Err(*x)}
}
fn接受(x:&T)->bool{
如果*x>9{panic!(“{}应该被验证器拒绝”)}
*x%2==0
}
我想写一个函数

fn计数\u已接受(数据:&[T])->结果
哪个

  • 在中遇到第一个无效元素时,立即返回
    Err(Err)
    输入数据

  • 如果所有元素都有效,则返回包含值计数的
    Ok(usize)
    满足
    接受
    标准的

下面是一个使用循环的解决方案:

fn计数循环(数据:&[T])->结果{
让mut count=0;
对于数据中的项{
有效(&项)?;
如果接受(&item){count+=1}
}
好(计数)
}
这些试验证明,其似乎按照要求工作:

宏规则!测试{
($count:path)=>{
#[test]fn empty(){assert_eq!($count(&[]),Ok(0))}
#[test]fn all_ok_和_accepted(){assert_eq!($count(&[2,6]),ok(2))}
#[test]fn all_ok_some_rejected(){assert_eq!($count(&[2,3]),ok(1))}
#[test]fn one_invalid(){assert_eq!($count(&[12]),Err(12))}
#[test]fn stop_on_first_invalid(){assert_eq!($count(&[2,13,6,12,5]),Err(13))}
}
}
mod test_loop{testem!{super::count_loop}
我想了解是否/如何使用 迭代器而不是循环

考虑一个相关但更简单的问题:如果有任何数据无效,请退出 立即输出,否则将所有数据收集到向量中。换句话说, 从上一个问题中删除
accept
条件

这个问题有一个非常令人满意的解决方案,因为迭代器的
fromtiterator
结果的实施
负责提前终止:

fn相关(数据:&[T])->结果{
数据.国际热核实验堆()
.map(有效)
.collect()
}
mod test_相关{
#[测试]
fn stop_on_first_invalid(){assert_eq!(super::related(&[2,13,6,12,5]),Err(13))}
}
这里是
相关
的扩展,它通过了与
计数循环
相同的测试:

fn count\u via\u vec(数据:&[T])->结果{
好(数据)
.国际热核实验堆(iter)
.map(有效)
.filter(|x | x.is_err()| | accept(&x.unwrap()))
收集::()?
.len())
}
mod test_vvec{testem!{super::count_via_vec}}
但是:该解决方案在
计数循环方面有许多缺点:

  • 过滤条件非常嘈杂

  • 当第一个无效项出现时,仍需要执行筛选步骤 已识别(与原始循环实现不同):出现
    如果有意义的话,比应该的晚2行

  • 矢量被不必要地填充(除非锈菌会导致某些冷却) 优化,我还没有意识到),所以空间复杂性从 O(1)至O(N)

最后一点通常通过替换
.collect::()?.len())
.count()
取消无效案例识别的进一步不利影响:它们
这些都被简单地算作成功,这可以从这次失败的测试中看出
实施:

fn计数迭代(数据:&[T])->结果{
Ok(数据
.国际热核实验堆(iter)
.map(有效)
.filter(|x | x.is_err()| | accept(&x.unwrap()))
.count())
}
mod test_iter{testem!{super::count_iterate}
您能推荐一些在迭代器方法链中提前返回的机制吗
这可以在这样的情况下使用?

您可能正在寻找的是,其中T:Sum
的结果有一个
impl Sum,而所有基本整数也有
Sum
的impl

因此,以下方法将起作用:

fn valid(x: &u32) -> Result<u32, u32> {
    if *x < 10 { Ok(1) } else { Err(*x) }
}

fn count(x: &[u32]) -> Result<u32, u32> {
    x.iter()
     .map(valid)
     .sum()
}

fn main() {
    println!("{:?}", count(&[13,1,2,3]));
}
fn有效(x:&u32)->结果{
如果*x<10{Ok(1)}否则{Err(*x)}
}
fn计数(x:&[u32])->结果{
x、 iter()
.map(有效)
.sum()
}
fn main(){
println!(“{:?}”,count(&[13,1,2,3]);
}

正如
Sum
上的文档所说,如果遇到错误,这将使迭代器短路。这将包括短路链式迭代器。

您可能要查找的是,其中T:Sum
的结果有一个
impl Sum,而所有基本整数也有
Sum
的impl

因此,以下方法将起作用:

fn valid(x: &u32) -> Result<u32, u32> {
    if *x < 10 { Ok(1) } else { Err(*x) }
}

fn count(x: &[u32]) -> Result<u32, u32> {
    x.iter()
     .map(valid)
     .sum()
}

fn main() {
    println!("{:?}", count(&[13,1,2,3]));
}
fn有效(x:&u32)->结果{
如果*x<10{Ok(1)}否则{Err(*x)}
}
fn计数(x:&[u32])->结果{
x、 iter()
.map(有效)
.sum()
}
fn main(){
println!(“{:?}”,count(&[13,1,2,3]);
}

正如
Sum
上的文档所说,如果遇到错误,这将使迭代器短路。这将包括短路链式迭代器。

您是否尝试了
try\u
迭代器方法<代码>为每一个进行尝试
似乎与您要查找的内容相似。你找到干净的解决方案了吗?谢谢我发现了一些朝着正确方向迈出的一步,但由于我已经远离铁锈好几个月了,我的记忆非常模糊。第一个是。另一个是,在某些情况下,错误的实现实际上对j