在Dart中修改类中的最终字段

Vic*_*aev 7 variables final dart

Dart文档阅读:

如果您从不打算更改变量,请使用final或const,而不是var或类型.最终变量只能设置一次;

好的,这意味着第二次分配最终变量将不起作用,没有任何关于修改的说法,即

void main() {
  final List<int> list = [1,2,3];  

  list = [10, 9, 8]; //error!

  list
  ..clear()
  ..addAll([10, 9, 8]); //works!
}
Run Code Online (Sandbox Code Playgroud)

从本质上讲,我可以看到,我重新分配了最终变量list.它是否与最终变量的整个概念相矛盾?

Gün*_*uer 9

final不代表deep final.

list即使修改列表内容,变量仍引用相同的列表实例.即使将任何可变实例分配给最终变量,也可以对其进行修改.想像

void main() {
  var l = [1,2,3];
  final List<int> list = l;  
}
Run Code Online (Sandbox Code Playgroud)

现在,你将无法修改通过引用列表中的项目l,因为该名单也被分配到最后一场list(包括listl引用相同的列表).这没有意义.

你可以做些什么来使列表不可变

final List<int> list = const[1,2,3];  
Run Code Online (Sandbox Code Playgroud)

现在您无法分配另一个列表,list也无法修改引用的列表的内容list.

另一种方式

  import 'dart:collection'
  ...
  var l = [1,2,3];
  final List<int> list = UnmodifiablyListView(l);
Run Code Online (Sandbox Code Playgroud)

现在您无法修改list或引用的列表的内容,list但您可以修改引用的内容l(list将反映所做的更改l).
如果您松开了引用,l则无法修改内容.

  var l = [1,2,3];
  final List<int> list = UnmodifiablyListView(l);
  l = null;
Run Code Online (Sandbox Code Playgroud)

final当你想要确保list字段永远不会被设置为时,这很好null.

class MyModel {
  final list = [];
}
Run Code Online (Sandbox Code Playgroud)

list领域是公开的,但没有人可以设置list为例如null.

var model = new MyModel();
...
model.list.forEach(print);
Run Code Online (Sandbox Code Playgroud)

永远不会失败,例如null doesn't have a method 'forEach'.
这类似但更简洁

class MyModel {
  var _list = [];
  List get list => _list;
}
Run Code Online (Sandbox Code Playgroud)