Scoping with Dart's final keyword
All blocks have their own scope:
void main() { if (true) { final x = 0; } final x = 10; //ok}
won't work:
void main() { final x = 0; for (var i = 0; i < 10; i++) { x = i + 1; //NoSuchMethodError: cannot assign to final variable 'x' print(x); }}
but this one will:
void main() { final x = 0; for (var i = 0; i < 10; i++) { final x = i + 1; //ok again print(x); }}
Because each iteration you say "i want a new final x"
They are block level finals and it's a new declaration each time. Since those are finals, not statics - it's expected behavior. At least, they can help you avoid some mistakes and provide code annotation that basically says: "won't change".
In short: yes.
Each block is its own scope. Every time you execute a block, it creates new instances of the variables in the block.
A "final" variable can only be initialized once, but every time you "execute" the declaration, a new unmodifiable variable is created. It doesn't matter whether the block is just a simple nested block, or it is a loop body, or even a function body.
main() { foo(1); foo(2);}void foo(final parameter) { final local = parameter * 2; for (final i in [1, 2]) { final block1 = local + i; { final block2 = local + i * 2; print(parameter * local * block1 * block2); } }}
In this example, all the final variables take more than one value during the life time of the program. Each time a final declaration is executed, the variable is introduced into the scope with a value, and when the block/scope is exited, the variable ceases to exist again.
The for(final i in ...)
is handled specially, so the i
variable is also created once for each loop iteration.