I'm using one class inside of another and having a hard time with initialization. This code won't compile because it says "The default value of an optional parameter must be constant" and MyClass(x:0)
is not a constant.
class UpperClass {
int a;
MyClass b;
UpperClass({this.a = 0, this.b = MyClass(x:0)});
}
class MyClass {
int x;
MyClass({required this.x});
}
Changing the constructor to this eliminates compiler errors:
UpperClass({a, b}) : this.a = a, this.b = b;
But the documentation says the preferred, equivalent is:
UpperClass({this.a, this.b});
but here the compiler complains that a and b are null.
I'd like to understand what's really going on here. Is it ok to use the constructor that compiles? Is there a better practice?
Your issue is that the value you want as default, MyClass(x: 0)
, is not a constant.
You can fix this in one of two ways.
The first is to make it constant, which means making the MyClass
constructor const
, which again requires all instance variable of MyClass
to be final. Then do , this.b = const MyClass(x: 0)
, at it will be allowed.
If that's too restrictive on MyClass
, if it really cannot be a class with a const
constructor, you cannot use a default value to initialize it.
Then you should make the parameter nullable, because an optional parameter must be nullable or have a default value (aka., it must have a default value, and if you don't write one, the default value will be null
, which must then be a valid value).
That means changing the UpperClass
constructor to:
UpperClass({this.a = 0, MyClass? b}) : b = b ?? MyClass(x:0);
If you do want to use the same instance of MyClass
every time, even if it isn't const
, you can create a default instance:
UpperClass({this.a = 0, MyClass? b}) : b = b ?? _defaultB;
static final MyClass _defaultB = MyClass(x:0);