4 ms·
So do all the functions have to have the same error type as the function that is calling them? I don't know rust, but in haskell notation, if a function returns
by tsuraan 10y ago
So do all the functions have to have the same error type as the function that is calling them? I don't know rust, but in haskell notation, if a function returns "Either x y" would it then only be able to use the "?" notation on functions that themselves return "Either x z", and not on functions that return "Either a b" (so, failure sides have to match, but success sides are flexible)?
EDIT:
Answering my own question: https://github.com/rust-lang/rfcs/blob/master/text/0243-trait-based-exception-handling.md https://github.com/rust-lang/rfcs/blob/master/text/0243-trai... makes it pretty clear; the error types must be the same. Which completely makes sense.
- steveklabnik 10y agoThey have to be convertible to the type that's being returned. You'd need an implementation of y -> z. It will call the conversion function for you. use std::fs::File; enum MyError { OhNo(String), } fn foo() -> Result<File, MyError> { Ok(File::open("foo.txt")?) } With only the above code, we get an error: the trait bound `MyError: std::convert::From<std::io::Error>` is not satisfied So by implementing it... use std::convert::From; use std::io; impl From<io::Error> for MyError { fn from(e: io::Error) -> MyError { // do some sort of conversion MyError::OhNo(String::from("some error")) } } Now `?` does the coercion automatically.
- tomtomtom777 10y agoThis is one of the things that makes Rust's error handling so elegant. The error "handling" code mostly part of the error types themselves, mostly in the form of to/from conversions. The actual logic code can then rely on these conversions and is freed from bloat.
- masklinn 10y ago> So do all the functions have to have the same error type as the function that is calling them? Not quite, they must have an error type convertible to the caller's error type, try! (and ?) really desugar to match val { Ok(v) => v, Err(e) => return Err(From::from(e)) } From is a generic conversion trait, a type A can implement From<B> in which case `From::from(b: B)` will yield an A (assuming A is either inferred or explicitly requested)