book
book copied to clipboard
Incorrect claim that the number of lines in an arm require braces
- I have searched open and closed issues and pull requests for duplicates, using these search terms:
- match
- lines
- I have checked the latest
mainbranch to see if this has already been fixed, in this file:- https://github.com/rust-lang/book/blob/main/src/ch06-02-match.md
URL to the section(s) of the book with this problem:
https://doc.rust-lang.org/book/ch06-02-match.html#the-match-control-flow-construct
Description of the problem:
If you want to run multiple lines of code in a match arm, you must use curly brackets, and the comma following the arm is then optional.
It turns out, according to the compiler, the condition which triggers the requirement for the curly brackets is not the fact that the code for the arm is spread over multiple lines. This version, putting everything on the same line for the arm:
Coin::Penny => println!("Lucky penny!"); 1
results in the error message "these statements are not surrounded by a body" indicating the portion of the line beginning with println!.
Conversely, spreading a single expression over multiple lines without enclosing the expression in curly braces compiles and runs just fine.
Suggested fix:
That depends on how the conflict between the earlier portions of the book (which assert that the value at the end of the line (without a semicolon) is an expression, not a statement) and the error message (which claims that it is a statement) should be resolved. If the compiler's message is correct, then the reworded sentence should read
If you want to include multiple statements in a match arm, you must use curly brackets, ...
Otherwise (that is, the book is right in saying 1 is an expression and not a statement), then it should read
If you want to include one or more statements in a match arm, you must use curly brackets, ...
I'm inclined to think the error message emitted by the compiler is just being sloppy in its wording, and the book's description of the distinction between a statement and an expression is correct, as that would match the semantics of those words as used for other languages. Regardless of which is correct, it is not correct to say that spreading an arm over multiple lines causes the compiler to require the use of braces.
Thanks for the attention to detail here! I suspect the reason the text uses a sort of “close enough” approach here is precisely because being more accurate requires being much wordier. It turns out that all statements are expressions (they produce ()), but not all expressions are statements, as you note. I don’t think the book has made that explicit at this point, though. I’m sympathetic to why they originally wrote “lines” here. 😂 I think “If you want to include any statements in a match arm…” will do the trick. Feel free to open a PR to that effect!
all statements are expressions (they produce ())
I think that's not valid in general @chriskrycho, or you could do let a = (let b = 6;);
You can do it with blocks, but that's a different matter (blocks are expressions returning () by default). Some (maybe all) expression-statements evaluate to () but not all statements, for example let statements.
Ah, yep, I was wrong there. Rust distinguishes between two kinds of statements: declaration statements and expression statements (per the reference).