3 ms·
So, semantically, what is `f(return)`? Are these examples supposed to actually do anything, or mirror actual code situations? Or is it just putting a monkey in
by bruce343434 5y ago
So, semantically, what is `f(return)`? Are these examples supposed to actually do anything, or mirror actual code situations? Or is it just putting a monkey in front of a typewriter?
- chrismorgan 5y agoIn Rust, just about everything’s an expression. `return` is an expression that diverges, meaning it’s of type never (spelled !, and coercible to any type, since you know the value will never actually be used). Here are another couple of ways of writing the same general concept: f({ return; () // () in this case because f takes a parameter of that type }); let x = return; f(x); So f() will never actually be called. You’ll get an unreachable_code warning on f. As a minimal case it’s mostly just funny, but the underlying concept does find its way into real Rust code, mostly in generated code (such as with macros). Also, although just about everything’s supposed to be an expression, sometimes things that can be an expression or a statement go a little bit funny, and return is a prime candidate for things going wrong in weird ways in the compiler frontend or in code generation or something, so it’s worthwhile having such tests (there will be more involved tests of return specifically elsewhere).
- skohan 5y agoSo does this mean if I call `f(return)`, it will return from the calling context without ever calling the function `f`?
- ben0x539 5y agoyes, it's roughly comparable to { let x = return; f(x) } where the call to f is clearly happening after an unconditional return. A slightly more practical example might be something like f(if blah() { 42 } else { return }) which works out to, roughly, { let x; if blah() { x = 42; } else { return; } f(x) } To get realistic, if you write f(g()?) you basically get f(match g() { Ok(x) => x, Err(e) => return Err(e), }) which is how rust does error propagation without exceptions and without constantly repeating a golang-style mantra.
- chrismorgan 5y agoBuilding on the more practical example, this sort of conditional early return is extremely common in Rust, because expression-orientation makes it very pleasant to use. Here’s a sketch of some of the sorts of ways it can happen in state machine: loop { // … state = match state { A => B, // normal B => break, // exits the loop C => { …; continue; }, // does something and then returns to the start of the loop, skipping setting the state and anything else D => return, // exits the whole thing E => f()?, // if f() returns an Err or None or similar, it’ll return early }; // … }
- brundolf 5y agoI always thought return, like assignment, could only be a statement and not an expression
- steveklabnik 5y agohttps://doc.rust-lang.org/stable/reference/expressions/return-expr.html#return-expressions https://doc.rust-lang.org/stable/reference/expressions/retur... They’re always expressions in Rust, though they are often written with ; to make an expression statement.
- chrismorgan 5y agoSee also https://doc.rust-lang.org/stable/reference/statements.html https://doc.rust-lang.org/stable/reference/statements.html on what statements are. Basically, the only thing that is a statement and can’t be an expression is `let pattern = expression;`.
- estebank 5y agoAnd even that will likely change in the future, letting you write things like if some_bool && let pat = expr {}