Is there any way to make use of the initializer list to optionally initialize optional parameters in a constructor? The following example resorts to if(?x) type logic in the body since it is not clear how to set _x in the initializer list only if it is passed in.
class Point { double _x = 0.0; double get x => _x; double _y = 0.0; double get y => _y; Point( { double x, double y }) { if(?x) { _x = x; } if(?y) { _y = y; } } }
An alternative is to have constructor:
Point( { double x: 0.0, double y: 0.0 }) : _x = x, _y = y { }
But then you are repeating yourself (0.0 more than one place) and it looks like _x and _y get initialized twice, once for the member and then again by the initializer list. Also, a benefit of member initializer is it can be a function call, whereas default values for default parameters seem to require constants. I hope/realize the performance impact is small. Just want a nice canonical approach, likely to be used in code generation.
You can initialize variables in a constructor using this
prefix, eg:
class PointA { double _x; double get x => _x; double _y; double get y => _y; PointA({double this._x=0.0, double this._y=0.0}); } class PointB { final double x; final double y; Point({double this.x=0.0, double this.y=0.0}); } void main() { new PointA(_y:2.0); new PointA(_x:3.0); new PointA(_x:2.0, _y:3.0); new PointB(y:2.0); new PointB(x:3.0); new PointB(x:2.0, y:3.0); }
Chris Buckett's answer is great for constants. Apparently there is a ternary operator that does work in member initializer. So if initialization of a field is expensive (say requiring a function call and/or creation of objects), this approach seems to work:
class Formats { static Map<String, dynamic> defaultFormats() { print("Expensive call - avoid if possible"); return {"th": 'default th', "td": 'default td'}; } Map<String, dynamic> leftTbl; Map<String, dynamic> rightTbl; Formats( {Map<String, dynamic>? leftTbl, Map<String, dynamic>? rightTbl}) : leftTbl = leftTbl ?? defaultFormats(), rightTbl = rightTbl ?? defaultFormats(); @override String toString() { return """ l => $leftTbl, r => $rightTbl """; } }
Sample use:
print(new Formats()); print(new Formats(leftTbl: {"th":'solid #089', "td":'solid #089' })); print(new Formats(leftTbl: {"th":'solid #189', "td":'solid #189'}, rightTbl: {"th":'solid #189', "td":'solid #189'}));
Output:
Expensive call - avoid if possible Expensive call - avoid if possible l => {th: default th, td: default td}, r => {th: default th, td: default td} Expensive call - avoid if possible l => {th: solid #089, td: solid #089}, r => {th: default th, td: default td} l => {th: solid #189, td: solid #189}, r => {th: solid #189, td: solid #189}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With