How to handle a Result<T, Err>


#1

I have a struct that has a new() method with a signature like this:

pub fn new(a: i32) -> Result<Rocket, RocketErr>

When I call the new() method I want to use the actual object if it’s good, or just ignore it if it throws an error.

I came up with some sample code that should help explain what I mean. I thought I might get away by matching the result as many time as I need it, but the variable gets moved so I can’t use it that way. I can’t figure out how to do it.

In C it would be something like

Rocket *rocket = NewRocket();
if (rocket != NULL) {
    // do something with it
}

// do some more stuff

// use it again if available
if (rocket != NULL) {
    // do something with it
}

Here’s the playground:
https://play.rust-lang.org/?gist=b4366c71bb783e7bc0a9ee9be868c400&version=stable&mode=debug


#2
let mut rocket = Rocket::new();
if let Ok(r) = &mut rocket {
    // `r` is a `&mut Rocket` borrow here
}

/// ...

if let Ok(r) = &mut rocket {
    // `r` is a `&mut Rocket` borrow again
}

/// ...

// may want to clean up by value now?
match rocket {
    Ok(mut r) => // owned rocket ...
    Err(e) => // owned error ...
}

#3

You can also use Result::as_ref() and as_mut() when you want to borrow it only:

match rocket.as_ref() { ... }
match rocket.as_mut() { ... }

#4

or

let mut rocket = Rocket::new(0);
match rocket {
    Ok(ref r) => {
        r.say()            
    },
    Err(_e) => {
        println!("error")
    }
}

// do something else in the middle here
match rocket {
    Ok(ref mut r) => {
        r.add(1)            
    },
    Err(_e) => {
        println!("error")
    }
}

#5

Thank you all for the suggestions guys. I don’t know which one is more idiomatic in Rust, but for the time being I went with @vitalyd solution. Cheers!