How do you unwrap a Result on Ok or return from th

2020-01-29 08:52发布

I have a function that calls another function which returns a Result. I need to check if the Result is Ok or Err and if it is an Err, I need to return early from my function. This is what I'm doing now:

match callable(&mut param) {
    Ok(_v) => (),
    Err(_e) => return,
};

Is there a more idiomatic Rust way to do this?

标签: rust
2条回答
祖国的老花朵
2楼-- · 2020-01-29 09:51

You can create a macro:

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);
}

Note that I wouldn't recommend discarding the errors. Rust's error handling is pretty ergonomic, so I would return the error, even if it is only to log it:

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!");
    }
}
查看更多
来,给爷笑一个
3楼-- · 2020-01-29 09:51

If both functions return Result<doesn't matter, same T> you can just put a ? at the end of line of call.

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

You can use same pattern for Option<T> too.

查看更多
登录 后发表回答