3

Based on my following code, I want to have a constructor of the class Hero that takes a Stats class as an optional parameter that has a default value based on its constructor (the one that set its health and attack fields to 100 and 10 by an optional named parameter) instead of null.

void main() {
  Hero hero = Hero("Foo");
  print('${hero.name} : HP ${hero.stats.health}');
}
class Stats {
  Stats({this.health = 100, this.attack = 10});
  double health;
  double attack;
}
class Hero {
  // error: The default value of an optional parameter must be constant
  Hero(this.name,[this.stats = Stats()]);
  String name;
  Stats stats;
}

More things i've tried:

class Hero {
  // error: Can't have a const constructor for a class with non-final fields
  Hero(this.name,[this.stats = const Stats()]);
  String name;
  Stats stats;
}
class Hero {
  // error: stats initialized as null
  Hero(this.name,[this.stats]);
  String name;
  Stats stats = Stats();
}

This following code works but it doesn't have stats as an optional parameter:

class Hero {
  Hero(this.name);
  String name;
  Stats stats = Stats();
}
Mario1159
  • 71
  • 1
  • 8

1 Answers1

4

(Credits to @jamesdlin for linking to his answer in the comments)

In general, if there isn't a const constructor available, you instead can resort to using a null default value (or some other appropriate sentinel value) and then setting the desired value later:

class Foo {
  Bar bar;

  Foo({Bar bar}) : bar = bar ?? Bar();
}

(Note that explicitly passing null as an argument will do something different with this approach than if you had set the default value directly. That is, Foo(bar: null) with this approach will initialize bar to Bar(), whereas with a normal default value it would initialize bar to null. In some cases, however, this approach's behavior might be more desirable.)

Mario1159
  • 71
  • 1
  • 8