? operator - propagating Result, Option errors: try block vs anonymous function

The ? operator - for propagating Result, Option errors.

According to:
https://doc.rust-lang.org/nightly/unstable-book/language-features/try-blocks.html
I can use

let r: Result<i32, std::num::ParseIntError> = try {
    "1".parse::<i32>()? };

But I can make use of anonymous function, like that:

let r: Result<i32, std::num::ParseIntError> = (|| -> Result<i32, std::num::ParseIntError> { 
    Ok("1".parse::<i32>()?) })();

What is the difference, what are pros and cons, and what for to introduce try block if I can achieve the same with anonymous function ?

You can also do:

let r: Result<i32, std::num::ParseIntError> = "1".parse::<i32>();

As for your question, the try blocks are syntactic sugar.
Even with only basic optimization, your examples compile to the same assembly:

2 Likes

I wanted to give simple example, perhaps to simple :slight_smile:
OK, so this:

let r: Result<i32, std::num::ParseIntError> = "1".parse::<i32>() + "2".parse::<i32>();

will not compile:

cannot add std::result::Result<i32, std::num::ParseIntError> to std::result::Result<i32, std::num::ParseIntError>

So above examples but a bit more complex:

let r: Result<i32, std::num::ParseIntError> = try {
    "1".parse::<i32>()? + "2".parse::<i32>()? };
let r: Result<i32, std::num::ParseIntError> = (|| -> Result<i32, std::num::ParseIntError> { 
    Ok("1".parse::<i32>()? + "2".parse::<i32>()?) })();

If using try block and anonymous function "is the same" then what for to introduce try block ?
Would not it be better to educate / describe / give examples of how to use anonymous function for that scenario ?

This will not compile either. I guess you meant:

let r: Result<i32, std::num::ParseIntError> = try { "1".parse::<i32>()? + "2".parse::<i32>()? };

And it's still the same:

Yes - my mistake that I have just realize.
I have just corrected original examples.

Even with non-const values the assembly code of both variants is equivalent:

You can't interact with the surrounding control flow structure with a closure. E.g. break from a loop, return from the containing function (not the closure).

5 Likes