Result
docs对.or_else()
方法提供以下说明:
fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F>
如果结果为Err则调用op,否则返回self的Ok值。
此功能可用于基于结果值的控制流程。
实施例
fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
fn err(x: u32) -> Result<u32, u32> { Err(x) }
assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2));
assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2));
assert_eq!(Err(3).or_else(sq).or_else(err), Ok(9));
assert_eq!(Err(3).or_else(err).or_else(err), Err(3));
我认为可以用更多的空格解析or_else
类型注释:
fn or_else<F, // F being the return type of the Result?
O: FnOnce(E) -> Result<T, F> // the function to run instead if error
>
(self, op: O) // arguments to the `.or_else()` method
-> Result<T, F> // return type is again Result
假设我已经做到了,那是否意味着.or_else()
只是给了Result
Error
,而op
替换为Result
函数的返回值?
我可以理解再次返回or_else()
,因为可能错误抛出的代码下游的所有代码都被&#34;染色&#34;有进一步错误的可能性(并且由调用者来处理)。但为什么在例子中加倍调用呢?有几种不同的排列,但我不确定他们试图展示的是什么(或者这种加倍的Json
模式是不是惯用的。)
答案 0 :(得分:8)
该示例可能有点不幸,因为它试图同时显示or_else
如何工作,以及为什么要使用它。
将其分成两部分。首先or_else
实际上做了什么。如果您在Ok
值上调用它,则会传递Ok
值。如果在Err
值上调用它,它将执行该函数。这个例子应该足够了:
Ok(2).or_else(sq), Ok(2) // not called
Ok(2).or_else(err), Ok(2) // not called
Err(2).or_else(sq), Ok(4) // called, succeeds
Err(2).or_else(err), Err(3) // called, fails
现在,你为什么要使用它呢?想象一下,你正在做一些有很多替代方法的操作。例如,您尝试在Linux上安装某个软件包,但不关心哪个软件包管理器可用 - 您只是打算强制它。所有返回Result<...>
的函数都可以执行此操作:
install_with_apt().
or_else(install_with_yum).
or_else(install_with_pacman).
or_else(install_with_dnf).
or_else...
你知道如果你回来Ok
,至少有一个成功了,如果你回来Err
,所有这些都失败了。如果可能只是试图向您显示,则示例中加倍.or_else()
用法可以轻松链接此调用。