story
func readNumberFromFileAndDoubleIt(filename string) (int, err) {
file, err = os.Open(filename)
if err != nil {
return 0, err
}
defer file.Close() // BUG!! this returns an error, but since we defer it, it is not going to be handled
bytes, err := ioutil.ReadFile(filename)
if err != nil {
return 0, err
}
contents := string(bytes)
i, err := strconv.Atoi(contents)
if err != nil {
return 0, err
}
return 2*i, nil
}
Rust (may contain syntax errors): fn read_number_from_file_and_double_it(filename: &str) -> Result<i32> {
let mut file = File::open(filename)?; // file automatically closed at end of scope
let mut contents = String::new();
file.read_to_string(&mut contents)?;
contents.parse().map(|i| 2*i)
}
4 vs 15 lines, I think it's obvious which one is easier to readAny practical code using Results soon ends up wanting to mix the errors from multiple sources. This requires a lot of boilerplate effort to make everything interop, and the machinery to reduce this is both complex and not standardised. If you don't go the upfront boilerplate-and-machinery route, things look awful.
And of course, if you use something else, like an Option, you're back to
let foo = match bar() {
Some(foo) => foo,
None => return None,
};
Go is much more consistent, and less pathological.Your example is especially disingenuous, though. For example, you chastise Go with
defer file.Close() // BUG!! this returns an error, but since we defer it, it is not going to be handled
but ignore the fact that this "bug" is nonoptionally hardcoded[1] into the Rust program. Which is it then?Rust's error handling looks nice on fake examples, and manageable inside self-contained libraries. My experience of actually using multiple libraries is that Rusts error handling is a choice between tangly handling of nested errors or verbose attempts to early-exit.
[1]: https://github.com/rust-lang/rust/blob/master/src/libstd/sys...
As to specifically whether I have used error-chain, not really. I no doubt will in the future, but I'm not seeing Rust on my plate for a while.