@@ -218,16 +218,50 @@ otherwise and allows more flexibility in code layout.
218
218
# Unresolved questions
219
219
[ unresolved ] : #unresolved-questions
220
220
221
- It would be possible to allow ` for ` , ` while ` and ` while let ` expressions return
222
- values in a similar way; however, these expressions may also terminate
223
- "naturally" (not via break), and no consensus has been reached on how the
224
- result value should be determined in this case, or even the result type.
225
- It is thus proposed not to change these expressions at this time.
221
+ ### Extension to for, while, while let
226
222
227
- It should be noted that ` for ` , ` while ` and ` while let ` can all be emulated via
228
- ` loop ` , so perhaps allowing the former to return values is less important.
229
- Alternatively, a keyword such as ` else default ` could be used to
230
- specify the other exit value as in:
223
+ A frequently discussed issue is extension of this concept to allow ` for ` ,
224
+ ` while ` and ` while let ` expressions to return values in a similar way. There is
225
+ however a complication: these expressions may also terminate "naturally" (not
226
+ via break), and no consensus has been reached on how the result value should
227
+ be determined in this case, or even the result type.
228
+
229
+ There are three options:
230
+
231
+ 1 . Do not adjust ` for ` , ` while ` or ` while let ` at this time
232
+ 2 . Adjust these control structures to return an ` Option<T> ` , returning ` None `
233
+ in the default case
234
+ 3 . Specify the default return value via some extra syntax
235
+
236
+ #### Via ` Option<T> `
237
+
238
+ Unfortunately, option (2) is not possible to implement cleanly without breaking
239
+ a lot of existing code: many functions use one of these control structures in
240
+ tail position, where the current "value" of the expression, ` () ` , is implicitly
241
+ used:
242
+
243
+ ``` rust
244
+ // function returns `()`
245
+ fn print_my_values (v : & Vec <i32 >) {
246
+ for x in v {
247
+ println! (" Value: {}" , x );
248
+ }
249
+ // loop exits with `()` which is implicitly "returned" from the function
250
+ }
251
+ ```
252
+
253
+ Two variations of option (2) are possible:
254
+
255
+ * Only adjust the control structures where they contain a ` break EXPR; ` or
256
+ ` break 'label EXPR; ` statement. This may work but would necessitate that
257
+ ` break; ` and ` break (); ` mean different things.
258
+ * As a special case, make ` break (); ` return ` () ` instead of ` Some(()) ` ,
259
+ while for other values ` break x; ` returns ` Some(x) ` .
260
+
261
+ #### Via extra syntax for the default value
262
+
263
+ Several syntaxes have been proposed for how a control structure's default value
264
+ is set. For example:
231
265
232
266
``` rust
233
267
fn first <T : Copy >(list : Iterator <T >) -> Option <T > {
@@ -239,8 +273,18 @@ fn first<T: Copy>(list: Iterator<T>) -> Option<T> {
239
273
}
240
274
```
241
275
242
- The exact syntax is disputed; (JelteF has some suggestions which should work
243
- without infinite parser lookahead)
244
- [ https://github.com/rust-lang/rfcs/issues/961#issuecomment-220728894 ] .
245
- It is suggested that this RFC should not be blocked on this issue since
246
- loop-break-value can still be implemented in the manner above after this RFC.
276
+ or:
277
+
278
+ ``` rust
279
+ let x = for thing in things default " nope" {
280
+ if thing . valid () { break " found it!" ; }
281
+ }
282
+ ```
283
+
284
+ There are two things to bear in mind when considering new syntax:
285
+
286
+ * It is undesirable to add a new keyword to the list of Rust's keywords
287
+ * It is strongly desirable that unbounded lookahead is required while syntax
288
+ parsing Rust code
289
+
290
+ For more discussion on this topic, see [ issue #961 ] ( https://github.com/rust-lang/rfcs/issues/961 ) .
0 commit comments