skip to Main Content

In the Dart documentation, it states that we should not place const before initializing a const constructor, as the keyword is already implicit.

However, can someone explain why the following codes exhibit different behaviors?

class Person{
  final List<String> names;
  
  const Person(this.names);
}

void main() {
  final Person person = Person(["Livia", "Lima"]);
  
  print(person.names);
  
  person.names.add("Carolina");
  
  print(person.names);
}
class Person{
  final List<String> names;
  
  const Person(this.names);
}

void main() {
  final Person person = const Person(["Livia", "Lima"]);
  
  print(person.names);
  
  person.names.add("Carolina");
  
  print(person.names);
}

In the first example, I can add "Carolina" to the list normally and get the following output:

["Livia", "Lima"]
["Livia", "Lima", "Carolina"]

However, in the second example, I get the following error:

Unsupported operation: add

Additionally, I have another question. Shouldn’t the list of names be immutable since it is declared as final?

2

Answers


  1. I think that Unsupported operation: add happens because list is also constant in second case. So basically it is :

      final Person person = const Person(const ["Livia", "Lima"]); // analyser will say second const is redundant
    

    And of course, because it is constant, it is immutable list.

    In first case, code does not invokes constant constructor because it must not be constant in this context. In that case, you should use at least one const modifier to show your intensions to compiler.

    So, yes. In first case person is not constant. In second case – it is constant indeed.

    Speaking of final and immutability (second question) – no, list not necessarily immutable if it is final. In that context, it only means that one can not reassign field names. But modifying that list is not prohibited

    Login or Signup to reply.
  2. Defining a constructor as const just means your class can produce Immutable objects (meaning it only contains consts or final variables).

    So this won’t compile:

    class Person {
      List<String> names;
    
      const Person(this.names);
    }
    

    The documentation states:

    Constant constructors don’t always create constants. They might be
    invoked in a non-const context.

    It further says:

    Some classes provide constant constructors. To create a compile-time
    constant using a constant constructor, put the const keyword before
    the constructor name:

    var p = const ImmutablePoint(2, 2);

    The part of the documentation you mentioned means that everything inside a constructor being called as const is also const. So the list being passed as a parameter is a const list in the second example. What that part of the documentation is saying not to do is:

     final Person person = const Person(const ["Livia", "Lima"]);
    

    Even

    final Person person = const Person(["Livia", "Lima"]);
    

    is not necessary you could just write

    const Person person = Person(["Livia", "Lima"]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search