Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I automatically return Ok(()) or None from a function?

Tags:

rust

I have functions that return an Option or a Result:

fn get_my_result() -> Result<(), Box<Error>> {
    lots_of_things()?;
    Ok(()) // Could this be omitted?
}

fn get_my_option() -> Option<&'static str> {
    if some_condition {
        return Some("x");
    }

    if another_condition {
        return Some("y");
    }

    None // Could this be omitted as well?
}

Currently, neither Ok(()) or None are allowed to be omitted, as shown in the examples above. Is there a reason for that? Is it possible for this to be changed in the future?

Update

We can use Fehler to write code like this:

#[throws(Box<Error>)]
fn get_my_result() {
    let value = lots_of_things()?;
    // No need to return Ok(())
}

Fehler also allows to throw as Option.

like image 893
Milack27 Avatar asked Oct 26 '18 13:10

Milack27


1 Answers

You cannot omit this in Rust. A proposal was made to allow a ()Result<(), _> coercion rule, but it was massively downvoted and then refused.

A comment explains well why it is a bad idea:

I've gotten very wary of implicit coercion because of JavaScript (yes, I know that's an extreme). I have always loved the explicitness of Rust, and that's why I have favored the other RFC more.

Here is an example of something I'm afraid of

let x = {
    // Do some stuff
    ...
    if blah {
        Ok(())
    } else {
        Err("oh no");
   }
};

if let Ok(_) = x {
    println!("this always prints");
}

Oops... In this case, the type system actually would give false confidence. Scary.

Also, more generally I would like the solution to be specific to exiting a function or block.


When I have a lot of Ok(()) in my code, I create a small helper function to make the code prettier:

fn ok<E>() -> Result<(), E> {
    Ok(())
}
like image 62
Boiethios Avatar answered Nov 02 '22 05:11

Boiethios