0

Consider this dart code:

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

My question is about whether passed items to List are copied over to List or it's a reference.
I've encountered this ambiguity because I'm using flutter_redux where an action contains an instance of class T. on reducer, I add this T instance to my state. later on, in the middleware, I update this t's id. But surprisingly id field on the state(in this case List) changes too! So my only guess is that objects are passed by reference. Is this assumption correct?

Mehrdad Shokri
  • 1,974
  • 2
  • 29
  • 45
  • Dart doesn't have copy constructors. It's not possible for a List to create a deep copy even if it wanted to since it's not possible to do generically. – jamesdlin Aug 16 '20 at 22:41

1 Answers1

0

Everything in Dart is an Object, so anything you are passing is passed by reference.

From the Dart Language Tour:

Everything you can place in a variable is an object, and every object is an instance of a class. Even numbers, functions, and null are objects. All objects inherit from the Object class.

mutable/immutable objects

There is a difference however between mutable and immutable objects. Some objects are immutable, and therefore cannot be modified, while mutable objects can be modified.

An example of immutable objects is String objects.

An example of mutable object is List just like you observed in your example.

constness

Dart has another interesting type of object, and if you are familiar with C++ or C, you would have encountered these. These are compile-time constants (const), and carry with them an attribute of immutability. Any object can be declared as const at the point of creation, provided the constructor being called has been declared as const.

Watch out with const objects if you are passing them to functions that expect mutable objects because attempting to mutate the constant, will result in a runtime error.

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

Running the above program will result in an Uncaught Error because l is a compile-time constant.

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

smac89
  • 39,374
  • 15
  • 132
  • 179