当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Rust Iterator.try_fold用法及代码示例


本文简要介绍rust语言中 std::iter::Iterator.try_fold 的用法。

用法

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where    F: FnMut(B, Self::Item) -> R,    R: Try<Output = B>,

一个迭代器方法,只要函数成功返回,它就会应用一个函数,产生一个单一的最终值。

try_fold() 接受两个参数:一个初始值和一个带有两个参数的闭包:一个 'accumulator' 和一个元素。闭包或者成功返回,并返回累加器下一次迭代应具有的值,或者返回失败,并立即将错误值传播回调用者(短路)。

初始值是累加器在第一次调用时将具有的值。如果对迭代器的每个元素应用闭包成功,try_fold() 将最终累加器返回为成功。

每当你有一些东西的集合并想从中产生一个值时,折叠很有用。

给实施者的注意事项

就这一方法而言,其他几个(前向)方法具有默认实现,因此如果它可以比默认的for 循环实现做得更好,请尝试显式实现它。

特别是,尝试在组成此迭代器的内部部件上调用 try_fold()。如果需要多次调用,? 运算符可能便于将累加器值链接起来,但要注意在早期返回之前需要维护的任何不变量。这是&mut self 方法,因此在此处遇到错误后需要可恢复迭代。

例子

基本用法:

let a = [1, 2, 3];

// the checked sum of all of the elements of the array
let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x));

assert_eq!(sum, Some(6));

短路:

let a = [10, 20, 30, 100, 40, 50];
let mut it = a.iter();

// This sum overflows when adding the 100 element
let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
assert_eq!(sum, None);

// Because it short-circuited, the remaining elements are still
// available through the iterator.
assert_eq!(it.len(), 2);
assert_eq!(it.next(), Some(&40));

虽然你不能从闭包中break,但 ControlFlow 类型允许类似的想法:

use std::ops::ControlFlow;

let triangular = (1..30).try_fold(0_i8, |prev, x| {
    if let Some(next) = prev.checked_add(x) {
        ControlFlow::Continue(next)
    } else {
        ControlFlow::Break(prev)
    }
});
assert_eq!(triangular, ControlFlow::Break(120));

let triangular = (1..30).try_fold(0_u64, |prev, x| {
    if let Some(next) = prev.checked_add(x) {
        ControlFlow::Continue(next)
    } else {
        ControlFlow::Break(prev)
    }
});
assert_eq!(triangular, ControlFlow::Continue(435));

相关用法


注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 std::iter::Iterator.try_fold。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。