3 ms·
Suppose you have two functions fn f() -> Result<A, E> fn g() -> Result<B, E> Then you can write fn h() -> Result<(A,B), E> { let x = f()
by lower 9y ago
Suppose you have two functions
fn f() -> Result<A, E>
fn g() -> Result<B, E>
Then you can write
fn h() -> Result<(A,B), E> {
let x = f()?;
let y = g()?;
Ok((x, y))
}
rather than having to do something like
fn h() -> Result<(A,B), E> {
match f() {
Ok(x) => {
match g() {
Ok(y) => Ok((x,y)),
Err(e) => Err(e)
}
},
Err(e) => Err(e),
}
}
(written from memory, please excuse syntax errors)
What's new is that this also works with Option<A> now.
- zZorgz 9y agoAs others mentioned, it looks equivalent to using the try! macro (which I'm not sure this is supposed to replace?) Another sane alternative here is using and_then, map, etc. Writing from memory too: fn h() -> Result<(A, B), E> { f().and_then(|x| g().map(|y| (x, y))) } ..which seems to be a different style of control flow to choose from. On one hand, I suppose one may avoid using and_then with code dealing with side effects. On another hand, ? seems restricted to being used inside functions that have to return a a single type (like Result) they operate on.
- steveklabnik 9y ago? is explicitly a replacement for try!, yes. > functions that have to return a single type Well, all functions have to return a single type, though that type may be a composite type, like a tuple. Less pedantically, `?` lets you (well, will let you) unwrap values and convert their error cases between each other. So once the next round of stabilization happens, if you have a function that returns Results, you can mix ? on Options and Results in the body, and vice versa. And it can be extended for other types too. Basically, it's an early return "protocol" if you will.
- zZorgz 9y agoBy single type, I meant to hint not being able to mix ? on Options and Results in the body, but good to know that's soon possible! Though you still can't, eg, use `?` in main()
- steveklabnik 9y agoThat's coming as well!
- zZorgz 9y agoInteresting. Looking at the proposal it seems specific to main() and not any void returning function, by automatically picking an exit status. I suppose I worry the construct has a lack of control (log diagnostics, exit status, cleaning, etc) when bailing and can’t handle eg continue, break too.
- steveklabnik 9y agoexit status and cleaning should be just fine, logging or something else would need to not do it, yeah. continue and break would be weird outside of loops.
- zZorgz 9y agoAlso regarding an "early return protocol", I'd also be curious for continue, break, any ! type expression. For one of the Rust projects I worked on, I wrote an unwrap macro on Option that takes a secondary ! argument.
- kibwen 9y agoTracking issue for using it in main: https://github.com/rust-lang/rust/issues/43301 https://github.com/rust-lang/rust/issues/43301
- mmstick 9y agoYou can mix them if you take your Options and convert them into Results with the Option::ok_or(E) method. do_this(x).ok_or(CustomError::ThisError)?;