【发布时间】:2018-12-23 00:07:38
【问题描述】:
我有一个函数调用另一个返回Result 的函数。我需要检查Result 是Ok 还是Err,如果是Err,我需要从我的函数中提早return。这就是我现在正在做的事情:
match callable(&mut param) {
Ok(_v) => (),
Err(_e) => return,
};
有没有更惯用的 Rust 方法来做到这一点?
【问题讨论】:
标签: rust
我有一个函数调用另一个返回Result 的函数。我需要检查Result 是Ok 还是Err,如果是Err,我需要从我的函数中提早return。这就是我现在正在做的事情:
match callable(&mut param) {
Ok(_v) => (),
Err(_e) => return,
};
有没有更惯用的 Rust 方法来做到这一点?
【问题讨论】:
标签: rust
您可以使用我的unwrap_or crate 来完成此操作。
你可以这样做:
unwrap_or_ok!(callable(&mut param), _, return);
如果你想要结果并返回错误,你可以这样做:
let v = unwrap_or_ok!(callable(&mut param), error, return error);
【讨论】:
您可以创建一个宏:
macro_rules! unwrap_or_return {
( $e:expr ) => {
match $e {
Ok(x) => x,
Err(_) => return,
}
}
}
fn callable(param: &mut i32) -> Result<i32, ()> {
Ok(*param)
}
fn main() {
let mut param = 0;
let res = unwrap_or_return!(callable(&mut param));
println!("{:?}", res);
}
请注意,我不建议放弃错误。 Rust 的错误处理非常符合人体工程学,所以我会返回错误,即使只是记录它:
fn callable(param: &mut i32) -> Result<i32, ()> {
Ok(*param)
}
fn run() -> Result<(), ()> {
let mut param = 0;
let res = callable(&mut param)?;
println!("{:?}", res);
Ok(())
}
fn main() {
if let Err(()) = run() {
println!("Oops, something went wrong!");
}
}
【讨论】:
return 还是continue。这是惯用的锈吗?
? 运算符有什么区别?
? 运算符只能在返回 Try 实现者的函数中使用。 OP想要从一个返回unit的函数返回,而unit没有实现Try。
Result的run()来添加间接是个好主意,原因有两个:1)在run()内部,您可以使用?来处理错误返回; 2) 然后您可以在一个地方记录/处理所有错误返回。 IMO,这比创建宏要好。
foo 返回 () 并且我们还想使用 ?要在foo 中提前返回,最好添加一层bar() -> Result(),其中包含允许的实际代码?提前返回,然后foo 将调用bar 并记录错误。
如果两个函数都返回Result<doesn't matter, same T>,您可以在调用行的末尾添加?。
fn caller() -> Result<Str, i32> {
let number = job()?; // <-- if job return error this function return/end here
// otherwise the value of Ok will assign to number
Ok(format!("the number is {}", number))
}
fn job() -> Result<i32, i32> {
// do something
Err(3)
}
Option<T> 也可以使用相同的模式。
【讨论】:
Err(_e) => return,