0

I know that dart is passing by value just like Java, but I don't understand why in the following example it acts like passing by reference?

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

The result will be

20
20

why when the variable (y) for the object (a) was changed inside the method (add) inside (b), it also changed the variable (y) of the object (a) inside main()?

julemand101
  • 28,470
  • 5
  • 52
  • 48
  • 2
    Did you also try the same thing in Java and observed something different? – smac89 Sep 26 '20 at 17:05
  • 1
    Does this answer your question? [What is the true meaning of pass-by-reference in modern languages like Dart?](https://stackoverflow.com/questions/25170094/what-is-the-true-meaning-of-pass-by-reference-in-modern-languages-like-dart) – jamesdlin Sep 26 '20 at 18:24

2 Answers2

2

Dart is call-by-value. The values are object references. That's sometimes also called "call by sharing" or "call by object reference". It is call-by-value ... for a specific choice of values.

Objects have identity, that's one of the fundamental cornerstones of object oriented programming. Because of that, you cannot copy them without it becoming a new object. That's why object oriented languages generally don't store objects in variables, they store references to objects. Those references are then passed by value.

Call-by-value differs from call-by-reference in that the latter passes variables (also known as L-values, the thing on the left of an assignment), not their values (R-values). Call-by-reference allows you to create a local variable, pass it by reference to another function, and have that function change the value bound to the variable. Dart cannot do that, it can only pass the value of the variable.

Objects can contain variables (instance variables, aka. fields), so you can pass a reference to an object containing a variable (by value), which allows a function to mutate something through the parameter, but that something cannot be a local variable.

lrn
  • 64,680
  • 7
  • 105
  • 121
1

I think your confusion comes from a misunderstanding about what variables and parameters are and the concept of pass by reference and pass by value.

A variable in Dart can be seen as a reference to a object. When you give this variable as a parameter to a method you are essential given a copy of this reference. The method can therefore not change what object this reference are pointing to. But the method do have access to the object itself since it got a copy of the reference. We are therefore not creating copies of objects when we give a variable to a method.

Some objects in Dart are immutable (like String, int, double etc.) so a method will not be able to change the inner state of these types of objects. So even if we got a copy of a reference to some of these objects, we cannot change the state and therefore we seen this like "pass by value" behavior.

But if an object (e.g. List) are able to change its inner state, we can make modification like adding items to a List object. Since we never create new objects we will see this change outside our method since we have made a change to the object itself without any change to the reference. This gives this "pass by reference" behavior you see in your example.

But this does not change the fact that the variable itself are a reference which always "pass by value" when given to methods as parameter.

A small example showing what I mean by "pass by value" when we talk about parameter to methods, can be seen here:

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

As the example shows, the a variable in myMethod can be changed to point to another object but since this variable is pass by value, the change will not happen in main.

julemand101
  • 28,470
  • 5
  • 52
  • 48