【问题标题】:Modifying final fields inside the class in Dart在 Dart 中修改类内的最终字段
【发布时间】:2014-10-07 12:19:59
【问题描述】:

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

正如大家所见,本质上,我重新-分配了最终变量list。这不是与最终变量的整个想法相矛盾吗?

【问题讨论】:

    标签: variables dart final


    【解决方案1】:

    final 不代表 final

    即使您修改了列表内容,list 变量仍然引用相同的列表实例。任何可变实例都可以修改,即使它已分配给最终变量。 想象一下

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

    现在您将无法修改l 引用的列表中的项目,因为该列表也分配给了最后一个字段listlistl 都引用了同一个列表)。这没有意义。

    使列表不可变的方法是

    final List<int> list = const[1,2,3];  
    

    现在您不能将另一个列表分配给list,也不能修改list 引用的列表的内容。

    另一种方法

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

    现在您不能修改listlist 引用的列表内容,但可以修改l 引用的内容(list 将反映对l 所做的更改。 如果您失去对l 的引用,您将无法修改内容。

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

    final 很好,例如,当您希望确保 list 字段永远不会设置为 null

    class MyModel {
      final list = [];
    }
    

    list 字段是公开的,但没有人可以将list 设置为例如null

    var model = new MyModel();
    ...
    model.list.forEach(print);
    

    不会因为null doesn't have a method 'forEach'之类的异常而失败。
    这与

    类似,但更简洁
    class MyModel {
      var _list = [];
      List get list => _list;
    }
    

    【讨论】:

    • 但是,如果一个编码void main() { final List&lt;int&gt; list = [1,2,3]; List&lt;int&gt; l=list; l=[10,9,8]; },那么l=[10,9,8] 将创建list 的深层副本;在调试器中可以清楚地看到:在第 2 行,llist 的 id 将相同,即它们引用内存中的同一个对象,而在第 3 行,这些引用将不同。我同意,你的第一个例子没有任何意义,但我描述的行为似乎也不是很有意义,即如果有这样一种简单的方法来重新分配它们,为什么还有决赛?上一条评论不正确。
    • 我不知道您为什么认为创建了深层副本。使用l = [10,9,8];,您创建了一个具有不同值的新(第二个)列表。 list 仍然引用第一个列表,l 引用完全不同的列表。
    • 是的,我误解了这个案例。感谢您的解释。
    猜你喜欢
    • 2014-02-22
    • 2021-01-30
    • 2021-11-18
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多