1
votes

In Dart, I see that it is possible to create const constructors within a class. Is it possible to mix a normal and const constructor within a class using the same fields? Or is it intended to always separate classes used for purposes of creating mutable and immutable instances?

I have tried creating a normal and const constructor in the same class. The issue is const constructors require final fields, and so if a normal constructor were to use these fields, then its instance fields would be immutable.

void main() {
  Jank fj = Jank.normal(5, 'LOL');
  const cj = const Jank.fixed(6, 'HA');

  fj.a = 123;       //cannot do this, but want to
  cj.a = 456;       //cannot do this, is expected
}

class Jank {
  final int a;
  final String b;

  Jank.normal(this.a, this.b);
  const Jank.fixed(this.a, this.b);
}

I want to be able to use immutable fields when using the const constructor, and use mutable fields when using the normal one. It seems to be one or the other.

1

1 Answers

2
votes

You can have non-const constructors on a class with const constructors, but all fields still need to be final.

You can also use new (implicit) with a const constructor (but not the other way around).

So the difference with a non-const constructors is that the constructor can have a body but it can not do much because it can't update the classes state. It can only invoke changes to states outside of the const instance.

A way around that would be using an Expando

The constructor initializer list allows more expressions because they are not limited to the few only allowed in const context.

So in overall mixing const and non-const is rather limited and only used for edge cases.

What you could do is create a different class that implements the class with the const constructor and instantiate it transparently using a factory constructor.

class Foo {
  final int value;

  const Foo(this.value);

  factory Foo.nonConst(int val) => _Bar(val);
}

class _Bar implements Foo {
  int _value
  int get value() => _value;

  Bar(int val) {
    _value = val * 5;
  }
}