rust 我怎样才能把这个循环重写为一个闭包?

icomxhvb  于 2023-01-17  发布在  其他
关注(0)|答案(3)|浏览(232)
let mut result = some_func();
for s in some_iterator {
    if result.is_ok() {
        break;
    }
    thread::sleep(time::Duration::from_millis(10));
    result = some_func();
}
// use result

我有一个代码看起来像上面那样,正在重新尝试调用some_func()。在这里,我必须将result声明为mut,以便在重试过程中更新它。是否有一些函数魔法可以让我不必将result声明为mut
我考虑了下面的示例,但不认为这是一个理想的示例,因为我必须迭代some_iterator的每个元素,这不是我想要的

let result = some_iterator.fold(some_func(), |result, x| {
    if result.is_ok() {
        return result; 
    }
    // sleep and retry 
});
brc7rcf0

brc7rcf01#

不要这样做,因为这样的代码很难适应不断变化的需求,比如“增加总超时”、“增加最大重试计数”、“在不可重试的错误时中止”或者“进行指数回退”。
相反,创建一个适当的RetryStrategy抽象,你只需要给予一个“fetch”闭包或者一个“is error fatal”闭包,最好使用一个已经存在的闭包,比如retry或者backoff crate。

wpcxdonn

wpcxdonn2#

您可以使用try_fold,但这需要交换ResultOkErr变体:

trait<T, E> SwappedExt<T, E> {
    fn swap_result (self) -> Result<E, T>;
}

impl<T, E> SwappedExt<T, E> for Result<T, E> {
    fn swap_result (self) -> Result<E, T> {
        match self {
            Ok (x) -> Err (x),
            Err (e) -> Ok (e),
        }
    }
}

let result = some_func().or_else (|e|
    some_iterator.try_fold (e, |_, _| {
        thread::sleep(time::Duration::from_millis(10));
        some_func().swap_result()
    }).swap_result());
2admgd59

2admgd593#

您可以尝试以下操作:

retry_strategy.map(
    |_|some_func()
).skip_while(
    |i|if i.is_err(){
        thread::sleep(time::Duration::from_millis(10));
        true
    } else {
        false
    }
).next().unwrap().unwrap()

相关问题