Dart docs read:
If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once;
Ok, this means that assigning a final variable second time will not work, but nothing is said about modifying, i.e.
void main() {
final List<int> list = [1,2,3];
list = [10, 9, 8]; //error!
list
..clear()
..addAll([10, 9, 8]); //works!
}
As one can see, in essence, I re- assigned final variable list
. Doesn't it contradict the whole idea of final variables?
You can't change the value of a final variable: name = 'Alice'; // Error: a final variable can only be set once. The const keyword isn't just for declaring constant variables. You can also use it to create constant values, as well as to declare constructors that create constant values.
Once assigned a value, a final variable's value cannot be changed. final modifies variables. final should be used over const if you don't know the value at compile time, and it will be calculated/grabbed at runtime. if you have a const collection, everything inside of that is in const.
The final keyword is used to hardcode the values of the variable and it cannot be altered in future, neither any kind of operations performed on these variables can alter its value (state).
A variable with the final keyword will be initialized at runtime and can only be assigned for a single time. In a class and function, you can define a final variable. For Flutter specific, when the state is updated, everything in the build method will be initialized again.
final
doesn't mean deep final
.
The list
variable references still the same list instance even when you modify the lists content. Any mutable instance can be modified even when it was assigned to a final variable.
Imagine
void main() {
var l = [1,2,3];
final List<int> list = l;
}
Now you wouldn't be able to modify the items in the list referenced by l
because the list is also assigned to the final field list
(both list
and l
reference the same list). That doesn't make sense.
What you can do to make the list immutable is
final List<int> list = const[1,2,3];
Now you can't assign another list to list
and you can't modify the contents of the list referenced by list
.
An alternative way
import 'dart:collection'
...
var l = [1,2,3];
final List<int> list = UnmodifiablyListView(l);
Now you can't modify list
or the contents of the list referenced by list
but you can modify the contents referenced by l
(list
would reflect the changes made to l
).
If you loose the reference to l
you have no way of modifying the contents.
var l = [1,2,3];
final List<int> list = UnmodifiablyListView(l);
l = null;
final
is nice when you for example want to ensure that the list
field never is set to null
.
class MyModel {
final list = [];
}
The list
field is public but nobody can set list
to for example null
.
var model = new MyModel();
...
model.list.forEach(print);
will never fail with an exception like null doesn't have a method 'forEach'
.
This is similar but more concise than
class MyModel {
var _list = [];
List get list => _list;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With