Description
@munificent has a magnificent write-up of declaring constructors: #4169
One thing it says is that a this(final name)
introduces an instance variable with signature final dynamic name;
.
If the same thing was written the "old-style way":
abstract class Bar {
abstract final String name;
}
class Foo implements Bar {
final name;
Foo(this.name);
}
the final name
would be subject to interface type inheritance, giving Foo.namethe type
String`.
Should writing Foo
as:
class Foo implements Bar {
this(final name);
}
also be subject to interface inheritance, and only fall back to dynamic
if there is nothing to inherit (and an error if there are multiple super-interfaces whose combined super-interface doesn't have a unique most-specific type for name
).
If not, a quick-fix to create a declaring constructor from a non-declaring one would have to insert the type. (Which it probably can.)
And quick-fixing in the other direction would have to insert dynamic
on the field.
If it does inherit, then the two ways of writing the constructor are symmetric.
I think I prefer this, because I want to think of the parameters of this
as field declarations that happen to be written inside a constructor. And as a field declaration, it does get interface inheritance.
(If we do go with no inheritance, could it at least default to Object?
instead of dynamic
. Then the user will figure out that they forgot to write the type. Or is that a job for the "no implicit dynamic" language feature, let's call it "Dart 4.0"!)
@dart-lang/language-team