为什么 Dart 充当引用传递?

问题描述 投票:0回答:3

我知道dart就像Java一样按值传递,但我不明白为什么在下面的示例中它的行为就像按引用传递?

class A {
  int y = 10;
}

class B {
  List<A> list = [];
  void add(A a) {
    a.y = 20;
    list.add(a);
  }

  void runtest() {
    print(list[0].y);
  }
}

void main() {
  A a = A();
  B b = B();
  b.add(a);
  print(a.y);
  b.runtest();
}

结果将会是

20
20

为什么当对象(a)的变量(y)在(b)内的方法(add)内改变时,它也改变了对象(a)在main()内的变量(y)?

dart pass-by-reference pass-by-value
3个回答
2
投票

1
投票

Dart 中的某些对象是不可变的(如 String、int、double 等),因此方法无法更改这些类型对象的内部状态。因此,即使我们获得了对其中某些对象的引用的副本,我们也无法更改状态,因此我们看到这就像“按值传递”行为。

但是如果一个对象(例如

List

)能够改变其内部状态,我们就可以进行修改,例如向

List

对象添加项目。由于我们从不创建新对象,因此我们将在方法之外看到这种变化,因为我们对对象本身进行了更改,而没有对引用进行任何更改。这给出了您在示例中看到的“按引用传递”行为。

但这并没有改变变量本身是一个引用的事实,当作为参数传递给方法时,它总是“按值传递”。
一个小例子展示了当我们谈论方法参数时“按值传递”的含义,可以在这里看到:

class A { int value; A(this.value); } void main() { final a = A(1); print(a.value); // 1 myMethod(a); print(a.value); // 1 } void myMethod(A a) { a = A(2); }

如示例所示,

a
中的
myMethod

变量可以更改为指向另一个对象,但由于该变量是按值传递的,因此更改不会在

main
中发生。
    
好吧,让我们先设置一件事,dart 是按值传递的。总是。


0
投票
string

int

这样的基本类型,它的含义很明显,这意味着正在传递基本数据类型的实际值,但对于像对象这样的非基本类型(包括列表、映射和用户实例)定义的类),传递的

对对象的引用
因此,在您的情况下,当您调用 b.add(a); 时,您正在按值传递

a 的引用

。它仍然是

按值传递
,但是被传递的是引用,而不是对象本身。 因此,对 a 的引用所做的任何更改都会得到反映。

© www.soinside.com 2019 - 2024. All rights reserved.