Hi
I'm a newbie, so please be kind
When I want to handle error in C/python, I typically write code like this:
# code: python (non nested)
res = do_something()
if res is None:
return
res = do_something2(res)
if res is None:
return
I don't want to have multiple levels of nesting, for example I don't want the code above to be written as:
# python (nested)
res = do_something()
if res is not None:
res = do_something2(res)
if res is not None:
# and so on
The non-nested version is easier to read. In Rust, how do I implement the non-nested version? I've thought of 2 ways, but I don't know which is best or if there's a better version.
// Rust (non nested, Version 1)
let res = do_something();
if res == Err(e) {
eprintln!("Got error: {}", e);
return ();
}
let v = res.unwrap();
let res = do_something2(v);
if res == Err(e) {
eprintln!("Got error: {}", e);
return ();
}
let v2 = res.unwrap();
// ... and so on
There are 2 things about this code:
- the call to unwrap() is misleading. Someone who reads the code may conclude the code may panic, even though it will never since we catch the Err(e) with the if-statement
- unwrap() internally checks if res == Err(e), so there is some redundancy in the code. Will the compiler be able to remove the if-statement in unwrap() during compilation, since it's not needed?
One other way to code the non-nested version in Rust is as follows:
// Rust (non nested, Version 2)
let res = match do_something() {
Err(e) => { eprintln!("Got error: {}", e); return ();},
Ok(v) => v,
};
let res2 = match do_something2(res) {
Err(e) => { eprintln!("Got error: {}", e); return ();},
Ok(v) => v,
};
/// ... and so on
I feel Version 2 is better, but I'd like to hear from you experts !
Thanks so much!