【问题标题】:How can I re-write this loop as a closure?我怎样才能将这个循环重写为一个闭包?
【发布时间】:2023-01-12 16:47:51
【问题描述】:
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 = retry_strategy.fold(some_func(), |result, x| {
    if result.is_ok() {
        return result; 
    }
    // sleep and retry 
});

附言:如果你有更好的这篇文章标题,请告诉我

【问题讨论】:

  • some_iterator还是retry_strategy

标签: rust functional-programming


【解决方案1】:

你可以尝试这样的事情:

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()

【讨论】:

    【解决方案2】:

    不。使此类代码适应不断变化的需求要困难得多,例如“添加整体超时”、“添加最大重试次数”、“出现不可重试错误时中止”或“进行指数退避”。

    相反,创建一个适当的 RetryStrategy 抽象,您只需提供“fetch”闭包,也可能是“is error fatal”闭包。更好的是,使用一个已经存在的,比如 retrybackoff crate。

    【讨论】:

      【解决方案3】:

      你可以使用try_fold

      some_iterator.try_fold (some_func(), |_, _| {
          thread::sleep(time::Duration::from_millis(10));
          some_func()
      });
      

      【讨论】:

      • 这不是适得其反吗?打破第一个Err?另外,我认为这不会编译,因为 Result<T, E>T 的类型不匹配。
      猜你喜欢
      • 2020-08-14
      • 1970-01-01
      • 2018-06-10
      • 2017-06-25
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多