Modifying final fields inside the class in Dart

吃可爱长大的小学妹 提交于 2020-06-10 11:20:49

问题


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?


回答1:


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


来源:https://stackoverflow.com/questions/26235849/modifying-final-fields-inside-the-class-in-dart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!