Dart has the concept of compile-time constants. A compile-time constant is parsed and created at compile time, and canonicalized.
For example, here is a const
constructor for Point:
class Point {
final num x, y;
const Point(this.x, this.y);
}
And here's how you use it:
main() {
var p1 = const Point(0, 0);
var p2 = const Point(0, 0);
print(p1 == p2); // true
print(p1 === p2); // true
}
This is a non-obvious feature, with seemingly no parallels to features in other dynamic languages. There are restrictions on const
objects, like all fields must be final and it must have a const constructor.
Why does Dart have compile-time constants?
From the mailing list, Florian Loitsch writes:
The canonicalization property of compile-time constants is nice, but
not the main-reason to have them. The real benefit of compile-time
constants is, that they don't allow arbitrary execution at
construction and can therefore be used at places where we don't want
code to executed. Static variables initializers, for example, were
initially restricted to compile-time constants to avoid execution at
the top-level. In short, they make sure that a program starts with
'main' and not somewhere else.
Lasse's answer here helped me a lot
So, what are compile-time constants good for anyway?
- They are useful for enums.
- You can use compile-time constant values in switch cases.
- They are used as annotations.
Compile-time constants used to be more important before Dart switched
to lazily initializing variables. Before that, you could only declare
an initialized global variable like "var x = foo;" if "foo" was a
compile-time constant. Without that requrirement, most programs can be
written without using any const objects