0
votes

I can't add/delete/modify elements in a const list and in an unmodifiable list. So, what's the difference between the two if they both are doing the same thing?

3
Oops, you're right, I'm the one who was confused. Unlike C++, Dart has no notion of "const methods" and cannot at compilation-time determine what methods are allowed to be called on const objects.jamesdlin
@jamesdlin No worries sir, I deleted my comment.iDecode

3 Answers

1
votes

There is no difference because, slightly exaggerated, there is no "const list".

In Dart, being constant is not a property of a value, it's a property of an expression.

Example:

class Foo {
  final int x;
  const Foo(this.x);
}
main() {
  var foo1 = const Foo(1);
  var foo2 = new Foo(1);
  print(isConstant(foo1)); // cannot be done.
}

There is no way to write a general isConstant function which can distinguish an object created using const from one created using new. The run-time system has a list of the const-created objects somewhere (because it needs that to canonicalize another const Foo(1) to the same value), but the value itself doesn't know that it was created using a const expression.

List literals are slightly different from constructor based object creation because a non-const literal is mutable and a const literal is not. Instead the const literal creates a list object similar to the one you would create using List.unmodifiable. And again, the list object itself doesn't know whether it was created using const [...] or List.unmodifiable([...]), it just knows that it's an unmodifiable list with a specific set of values.

The VM actually uses the same class for both const lists and unmodifiable lists (dart2js uses JS Array for everything, but does mark them the same way as fixed-length and unmodifiable). The compilers didn't have to use the same class, it's an implementation detail how const lists are implemented, but it's also not surprising that they only have one implementation of an unmodifiable list, anything else would be wasteful.

So, there is no difference between a const list object and a list created using List.unmodifiable. They're instances of the same implementation class.

(Obviously, a constant variable holding a constant list can be used in other constant expressions, and constant list literals are canonicalized, so if you write const [1] two places in the program, it evaluates to the same list object, but the object itself is just an unmodifiable list).

0
votes

There's a difference. When you're using const for a List, you can only add constant values. However, this is not the case with an unmodifiable list.

var foo = 1;
const l1 = [foo]; // Compile-time error
final l2 = List.unmodifiable([foo]); // No error
0
votes

Another important difference is two equal const objects are guaranteed to be identical (so they points to the same internal object since the object is built on compile time) where two unmodifiable lists will always be two different objects:

void main() {
  final unmodifiableList1 = List<int>.unmodifiable(<int>[1,2,3]);
  final unmodifiableList2 = List<int>.unmodifiable(<int>[1,2,3]);
  print(identical(unmodifiableList1, unmodifiableList2)); // false

  const constList1 = [1,2,3];
  const constList2 = [1,2,3];
  print(identical(constList1, constList2)); // true
}