【问题标题】:Updating instance of class after being pushed to a List推送到列表后更新类的实例
【发布时间】:2020-08-16 19:56:02
【问题描述】:

考虑一下这个飞镖代码:

T t = T() // id field defaults to null
List<T> list = List()..add(t);
t.id = '123';
print('${list.first.id}') // What's output?

我的问题是传递给List 的项目是否被复制到List 或者它是一个参考。
我遇到了这种歧义,因为我使用的是flutter_redux,其中一个动作包含T 类的一个实例。在 reducer 上,我将这个 T 实例添加到我的状态中。稍后,在中间件中,我更新了这个 t 的 ID。但令人惊讶的是,状态(在本例中为列表)上的 id 字段也发生了变化!所以我唯一的猜测是对象是通过引用传递的。这个假设正确吗?

【问题讨论】:

  • Dart 没有复制构造函数。 List 不可能创建深层副本,即使它想这样做,因为一般情况下是不可能的。

标签: flutter dart flutter-redux


【解决方案1】:

Dart 中的所有内容都是一个对象,因此您传递的任何内容都是通过引用传递的。

来自Dart Language Tour

你可以放在变量中的所有东西都是一个对象,每个对象 是一个类的实例。偶数、函数和null 是 对象。所有对象都继承自 Object 类。

可变/不可变对象

然而,可变对象和不可变对象之间是有区别的。有些对象是不可变的,因此不能修改,而可变对象是可以修改的。

不可变对象的一个​​例子是String 对象。

一个可变对象的例子是List,就像你在你的例子中看到的那样。

常数

Dart 还有另一种有趣的对象类型,如果你熟悉C++C,你就会遇到这些。这些是编译时常量(const),并带有不变性属性。任何对象都可以在创建时声明为 const,前提是被调用的构造函数已声明为 const。

小心使用 const 对象,如果您将它们传递给期望可变对象的函数,因为尝试改变常量会导致运行时错误。

void modl(final List<int> l) {
  l.add(90);
  print(l);
}

void main() {
  List<int> l = const [1,2,3,4];
  modl(l); // Uncaught Error
  print (l);
}

运行上述程序将产生Uncaught Error,因为l 是编译时常量。

Detecting when a const object is passed to a function that mutates it, in Dart

【讨论】:

    猜你喜欢
    • 2020-03-16
    • 2020-10-03
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多