For loops
6 April 2012
First off, I want to welcome Brian Anderson to the Rust blog-o-sphere
(which so far consists primarily of myself). His first post
does a great job of explaining how to use the new for
syntax that
was recently added to Rust: this syntax allows for break
, ret
, and
cont
from within user-defined loops, which is very nice.
Reading some of the Hacker News comments
(this one in particular), I wanted to clarify one thing. There
is some concern that this new syntax changes the semantics of ret
when, in fact, it aims to do precisely the opposite.
The goal is that ret
always returns from the innermost enclosing
fn()
declaration. Sugared closures (e.g., {|x| ...}
) do not count
as an fn-declaration, but a closure written out with fn()
does. If
you use ret
from a context where the compiler cannot generate a
return from the innermost enclosing fn()
declaration, a static error
results.
Here are some examples of what I mean. First, the basic for
loop:
fn foo() {
for each(v) {|e|
ret e; // returns from foo()
}
}
Here I am using an fn@()
closure:
fn foo() {
let bar = fn@() -> T {
for each(v) {|e|
ret ...; // returns from bar()
}
ret ...; // returns from bar()
};
ret ...; // returns from foo()
}
and here is an example where an error results:
fn foo() {
iter(v) {|e|
ret e; // should return from foo(), but cannot
}
}
Note that returning out of sugared closures like {||...}
is only
allowed in the context of a for
loop, since it requires additional
code generation to support.