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 se
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 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 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 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 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;
}