Generative constructors in Dart support initializing formals, which are a concise way to assign the value of a constructor parameter to a
field.
class Point {
final int x;
final int y;
Point(this.x, this.y);
}
Their use makes the code more concise and less error-prone than manual initialization:
- there is reduced risk of a mismatch between the type of the parameter and the type of the field, because the initializing formal type can (and
usually is) omitted, in favor of the field type
- there is no risk of a mismatch between the name of the parameter and the name of the field, because the compiler emits an error if it can’t
find a field with the same name as the initializing formals
- there is no risk of forgetting to assign the parameter to the field in the body of the constructor
- there is no risk of wrongly assigning the parameter to itself, which can happen by forgetting to use the
this
keyword: value
= value
instead of this.value = value
Exceptions
The rule doesn’t apply when the constructor has to perform additional logic before assigning the parameter to the field, for at least one of the
parameters, because in that scenario there is not a one-to-one correspondence between the parameter and the field anymore.
class AClass {
int value1 = 1;
int value2 = 2;
AClass(int value1, int value2) {
value1 += value2; // value1 is modified before being assigned
this.value1 = value1; // Non applicable
this.value2 = value2; // Non applicable
}
}
The rule applies, however, when the constructor checks for preconditions on the value of the parameter, because the check can be done with
initializing formals as well.
class AClass {
int value1 = 1;
AClass(int value1, int value2) {
if (value1 >= 0) {
throw Exception('value1 must be negative');
}
this.value1 = value1; // Noncompliant
}
}