const constructor and const object in Flutter

Viewed 418

I am stuck with gasp about const constructor in Dart (Flutter).

Supposed that I have StatelessWidget with const constructor

class ChildWidget extends StatelessWidget {
  final String myText;

  const ChildWidget(
      {this.myText = ''});

  @override
  Widget build(BuildContext context) {
    return Text(
      myText
    );
  }
}

And using it in parent widget

class _ParentWidgetState extends State<ParentWidget> {
  String myText = 'Hello World';
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            const ChildWidget(myText: myText),
          ],
        ),
      ),
    );
  }
}

It shows error that myText is invalid const. But when I remove const keyword precede ChildWidget, everything will be OK. What happens? What are differences between have and does not have const keyword?

I supposed that const keyword will trigger const constructor in ChildWidget. Maybe Flutter implicitly creates normal constructor with the same argument such as const one and trigger this when not having const keyword?

Please explain it to me. Many thanks and have a good day.

1 Answers

const means "known at compile time". If you call a constructor with the const keyword, it will instead be created at compile time, and will be built into the application binary:

const child1 = ChildWidget(myText: "text");
const child2 = ChildWidget(myText: "text");
print(identical(child1, child2));  // prints "true"

Note, this only happens when the application is compiled in Ahead-of-time mode (AOT). In Flutter, this means "profile" or "release" mode.

The reason why your example fails is because myText is not known at compile time.

This can seem confusing, because you have typed 'Hello World' which is clearly known at compile time, but the compiler cannot prove this, so it rejects it.

myText is declared as a String, but for dart to know that it is const, it must also be declared with the const keyword.

If you replace String myText = "Hello World"; with:

static const myText = 'Hello World';

the compiler will know it is const and then you can use it in your const ChildWidget()

P.S. you are correct that Dart creates a non-const constructor alongside a const constructor. It is perfectly fine to not use const with a const constructor:

children: [
  ChildWidget(myText: myText)  // perfectly fine
]
Related