Statements and Loops
Statements run actions and choose control flow.
Blocks group statements as the bodies of declarations and control-flow
constructs, such as functions, if, loops, try, and using. Standalone
{ ... } and {} blocks are syntax errors, including inside another body.
Named functions, classes, interfaces, enums, global constants, type aliases, newtypes, imports, and file attributes belong at the top level of a file or namespace. They cannot appear inside function bodies or control-flow blocks. Use a closure when you need a function value inside a body.
Expression statements
Any expression may form a statement when followed by ;:
$value = 1;
$value++;
write_line!($value);
Discarding a value marked #[MustUse] raises an error. Use its result or pass
it to discard! to state that you meant to ignore it.
Every expression statement needs an expression; ; alone is a syntax error.
Final locals
final binds a local once:
final $rate = 0.1;
final $price = 250.0;
assert!($price * $rate == 25.0);
The declaration must be the local’s first assignment. Any later write in the same function or file body is a compile error. A final local still follows normal value rules: an object may change through the local, but the local cannot point to another object.
if
An if condition must be bool:
$value = -3;
if ($value < 0) {
$sign = 'negative';
} else if ($value == 0) {
$sign = 'zero';
} else {
$sign = 'positive';
}
assert!($sign == 'negative');
while and do ... while
while tests before each pass. do ... while runs its body once before the
first test:
$count = 0;
while ($count < 3) {
$count++;
}
do {
$count--;
} while ($count > 0);
assert!($count == 0);
for
A for loop keeps its setup, condition, and step in one header:
$sum = 0;
for ($number = 1; $number <= 5; $number++) {
$sum += $number;
}
assert!($sum == 15);
Each header section may hold a comma-separated expression list. An empty
condition acts as true:
$left = 0;
$right = 3;
for (; $left < $right; $left++, $right--) {
write_line!($left . ':' . $right);
}
foreach
foreach accepts an array, an Iterator<K, V>, or a ToIterator<K, V>:
$seen = vec[];
foreach (dict['a' => 1, 'b' => 2] as $key => $value) {
$seen[] = $key . $value;
}
assert!($seen == vec['a1', 'b2']);
Omit the key when it is not needed. The value target may be a destructuring pattern.
Array iteration uses the entries present when the loop begins. Changing the source does not change that walk.
Variable scope
Each file body, function, method, and closure has its own variable scope. Control-flow blocks do not create another variable scope. A variable assigned on only some paths remains undefined when execution took another path.
Functions cannot read file-scope variables. A closure captures the outer variables it uses.