const dart code example

Example 1: const constructor dart

Const constructor creates a "canonicalized" instance.

That is, all constant expressions begin canonicalized, and later these "canonicalized" symbols are used to recognize equivalence of these constants.

Canonicalization:

A process for converting data that has more than one possible representation into a "standard" canonical representation. This can be done to compare different representations for equivalence, to count the number of distinct data structures, to improve the efficiency of various algorithms by eliminating repeated calculations, or to make it possible to impose a meaningful sorting order.

This means that const expressions like const Foo(1, 1) can represent any usable form that is useful for comparison in virtual machine.

The VM only needs to take into account the value type and arguments in the order in which they occur in this const expression. And, of course, they are reduced for optimization.

Constants with the same canonicalized values:

var foo1 = const Foo(1, 1); // #Foo#int#1#int#1
var foo2 = const Foo(1, 1); // #Foo#int#1#int#1
Constants with different canonicalized values (because signatures differ):

var foo3 = const Foo(1, 2); // $Foo$int$1$int$2
var foo4 = const Foo(1, 3); // $Foo$int$1$int$3

var baz1 = const Baz(const Foo(1, 1), "hello"); // $Baz$Foo$int$1$int$1$String$hello
var baz2 = const Baz(const Foo(1, 1), "hello"); // $Baz$Foo$int$1$int$1$String$hello
Constants are not recreated each time. They are canonicalized at compile time and stored in special lookup tables (where they are hashed by their canonical signatures) from which they are later reused.

P.S.

The form #Foo#int#1#int#1 used in these samples is only used for comparison purposes and it is not a real form of canonicalization (representation) in Dart VM;

But the real canonicalization form must be "standard" canonical representation.

Example 2: constant dart

EDIT

Now that the flag --dart-define has been added to the different command lines of Flutter, the following answer no-longer applies.

Instead just declare constants wherever you want, and potentially refer to other answers.

While there are no technical issues with static const, architecturally you may want to do it differently.

Flutter tend to not have any global/static variables and use an InheritedWidget.

Which means you can write:

class MyConstants extends InheritedWidget {
  static MyConstants of(BuildContext context) => context. dependOnInheritedWidgetOfExactType<MyConstants>();

  const MyConstants({Widget child, Key key}): super(key: key, child: child);

  final String successMessage = 'Some message';

  
  bool updateShouldNotify(MyConstants oldWidget) => false;
}
Then inserted at the root of your app:

void main() {
  runApp(
    MyConstants(
      child: MyApp(),
    ),
  );
}
And used as such:


Widget build(BuilContext context) {
  return Text(MyConstants.of(context).successMessage);
}
This has a bit more code than the static const, but offer many advantages:

Works with hot-reload
Easily testable and mockable
Can be replaced with something more dynamic than constants without rewriting the whole app.
But at the same time it:

Doesn't consume much more memory (the inherited widget is typically created once)
Is performant (Obtaining an InheritedWidget is O(1))

Tags:

Dart Example