-
Notifications
You must be signed in to change notification settings - Fork 13.8k
loop_break_value: add documentation for book #41857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
52c3380
7d94b48
7488ff5
3f980be
7ab35b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,76 @@ The tracking issue for this feature is: [#37339] | |
|
||
[#37339]: https://github.com/rust-lang/rust/issues/37339 | ||
|
||
Documentation to be appended to section G of the book. | ||
|
||
------------------------ | ||
|
||
### Loops as expressions | ||
|
||
Like most things in Rust, loops are expressions, and have a value; normally `()` unless the loop | ||
never exits. | ||
A `loop` can instead evaluate to a useful value via *break with value*: | ||
|
||
```rust | ||
// Find the first square number over 1000: | ||
let mut n = 1; | ||
let square = loop { | ||
if n * n > 1000 { | ||
break n * n; | ||
} | ||
n += 1; | ||
}; | ||
``` | ||
|
||
The evaluation type may be specified externally: | ||
|
||
```rust | ||
// Declare that value returned is unsigned 64-bit: | ||
let n: u64 = loop { | ||
break 1; | ||
}; | ||
``` | ||
|
||
It is an error if types do not agree, either between a "break" value and an external requirement, | ||
or between multiple "break" values: | ||
|
||
```rust | ||
loop { | ||
if random_bool() { | ||
break 1u32; | ||
} else { | ||
break 0u8; // error: types do not agree | ||
} | ||
}; | ||
|
||
let n: i32 = loop { | ||
break 0u32; // error: type does not agree with external requirement | ||
}; | ||
``` | ||
|
||
For now, breaking with a value is only possible with `loop`; the same functionality may | ||
some day be added to `for` and `while` (this would require some new syntax like | ||
`while f() { break 1; } default { break 0; }`). | ||
|
||
|
||
#### Break: label, value | ||
|
||
Four forms of `break` are available, where EXPR is some expression which evaluates to a value: | ||
|
||
1. `break;` | ||
2. `break 'label;` | ||
3. `break EXPR;` | ||
4. `break 'label EXPR;` | ||
|
||
When no value is given, the value `()` is assumed, thus `break;` is equivalent to `break ();`. | ||
|
||
Using a label allows returning a value from an inner loop: | ||
|
||
```rust | ||
let result = 'outer: loop { | ||
for n in 1..10 { | ||
if n > 4 { | ||
break 'outer n; | ||
} | ||
} | ||
}; | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I think this is more to the point now. "unless the loop never exits" only applies to
loop
and not any loop that never exists (see how even we are getting confused by the terms),for
andwhile
always evaluate to()
. But diverging things are very niche, maybe we should just not mention this here?