Explicit and implicit return in functions

Hey gang!

When I read that Rust implicitly returns the last expression in a function! I thought, Oh, Cool! :sunglasses:
I got that, The official style is "return is only for early returns."

But, why is there a choice between explicit and implicit returns. What are the advantages ? :thinking:

It's purely a stylistic choice so there are no real advantages/disadvantages (other than lowering friction by following established style conventions).

Rust is an expression-oriented language (every chunk of code has a return value, including match, for, etc) so if you've got a long string of statements (e.g. a function body) it's redundant to finish with return foo; when writing foo is just as effective.

5 Likes

one of the advantages, is that in certain situations it makes certain code shorter.
for example, in the code below
there would be at least 5 different places that would need an explicit return
if fields.len() != 5 {
Err("incorrect number of fields for multiple choice")
} else {
let answer = convert_choice_to_number(fields[4])?;
let choices : Vec<_> = fields[3].split(':').map(String::from)
.collect();

        if choices.len() < 3 {
            Err("not enough choices")
        } else if choices.len() >= 7 {
            Err("too many choices")
        } else if (answer as usize) > choices.len() {
            Err("answer must be a choice")
        } else {
            Ok(MultipleChoice {
                question: String::from(fields[2]),
                choices,
                answer,
            })
        }
    } //outside if
}

well, the official guide doesnt mention it but the borrow checker and immutability by default in addition to being eop based allows rust to wield it self to a more functional style

1 Like

Thanks for the replies! I can see that its mostly a style choice.

Well, this went straight above my head! Mind breaking down a bit for me ? Thanks!

"Implicit return" gives you the wrong mental model. It's not an implicit return. It's that Rust is an expression-based language.

As an expression-based languages, most things are expressions, and expressions evaluate to a value. Blocks are expressions, and so the final value of a block is that block's value. Functions are blocks.

If Rust truly had "implicit return", code like this would work:

fn foo(param: bool) -> i32 {
    if param { 5 };

    println!("param is: {:?}", param);

    6
}

But this doesn't work. You have to use return if you want to produce a value other than the final value of the block.

The official style, then, is to leave off the return in the trailing position because it's redundant.

Does that make sense?

11 Likes

Thanks for this, now its clear! :slightly_smiling_face:

1 Like

sorry, eop stands for expression oriented programming.
immutability by default generally lends a lot of rust to be written what some might describe as a "functional style".
by default you really don't use side effect generating functions very often because of the two features above

1 Like

The compiler is asking you to use a return statement which is very expressive