我刚看到拉取请求中的以下更改:
- .ok_or(Error::new(ErrorKind::Other, "Decode error"));
+ .ok_or_else(|| Error::new(ErrorKind::Other, "Decode error"));
Run Code Online (Sandbox Code Playgroud)
我所知道的唯一区别是:
ok_or我们已经创建Error的Error::new,并通过它变成一个适配器.ok_or_else我们已经传递了一个闭包,它会产生这样一个值,但是如果有Some数据则可能不会被调用Option.我错过了什么吗?
She*_*ter 14
主要原因使用ok_or_else或任何的..._or_else方法是避免在执行一个函数的不需要的时候.在的情况下,Option::ok_or_else或者Option::unwrap_or_else,有没有必要运行额外的代码时Option是Some.这可以使代码更快,具体取决于错误情况中发生的情况
在这个例子中,Error::new可能执行分配,但它也可以写入标准输出,发出网络请求,或任何Rust代码可以做的任何事情; 从外面很难说出来.将这些代码放在闭包中通常更安全,因此在成功案例发生时您不必担心无关的副作用.
Clippy也为你提供了这个:
warning: use of `unwrap_or` followed by a function call
--> src/main.rs:3:15
|
3 | let foo = foo.unwrap_or("hello".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `foo.unwrap_or_else(|| "hello".to_string())`
|
= note: #[warn(or_fun_call)] on by default
= help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#or_fun_call
Run Code Online (Sandbox Code Playgroud)
除了性能影响之外,ok_or如果不够小心,更复杂的参数可能会产生意想不到的结果。考虑以下情况:
fn main() {
let value: Option<usize> = Some(1);
let result = value.ok_or({ println!("value is not Some!"); 0 }); // actually, it is
assert_eq!(result, Ok(1)); // this holds, but "value is not Some!" was printed
}
Run Code Online (Sandbox Code Playgroud)
这本来可以避免ok_or_else(其他*_or_else函数也是如此),因为如果变体是Some.
| 归档时间: |
|
| 查看次数: |
1551 次 |
| 最近记录: |