ruipacheco
ruipacheco

Reputation: 16402

Why can't this be done with if?

I'm trying to handle errors received from an async call:

let res: Result<TcpStream, Box<dyn std::error::Error>> = session.runtime().borrow_mut().block_on(async {
    let fut = TcpStream::connect(session.configuration().socket()).await?;
    Ok(fut)
});

I tried to do it the old school way with an if but the compiler didn't like it:

if res.is_err() {
    return Err(res);
}

After some googling I came across this:

let mut stream = match res {
    Ok(res) => res,
    Err(res) => return Err(res),
};

which feels very much the same but with Rusts' equivalent of a switch statement. Why can't I use the if?

Upvotes: 0

Views: 78

Answers (1)

user4815162342
user4815162342

Reputation: 154886

if res.is_err() { return res } should work. Result is an enum with two variants: Ok which by convention holds a "successful" result, and Err which holds error information. As John pointed out, wrapping the existing Result (which happens to hold an Err) in another Err result doesn't make sense - or, more precisely, doesn't match the return type of the function.

When you use match, you unpack the result into its constituent values, and then in the error case re-pack it into a new result. Note that instead of the match statement use can use the ? operator, which would compress the declaration to just:

let mut stream = res?;

Upvotes: 1

Related Questions