Constants
The Dart language supports the const keyword, which results in values or identifiers that are derived and assigned at compile time. The values are then immutable. A const differs from a final in that finals are assigned at run time.
Constant Objects
Dart supports the keyword const for object instantiation. If an object is declared as being instantiated via the const keyword, it’s assigned a value at compile time.
A constant is an instance that is initialized with one of the following:
- A value of a primitive type
- A literal value derived by using only basic or bitwise operators
- A constant constructor
A const does not have access to any run-time values or helper functions to derive its value.
Constant Identifiers
Dart supports the keyword const for identifiers. A const identifier is a marked identifier that is assigned a constant object at compile time. It differs from a variable in that it is a named identifier, but its assigned value also cannot be changed.
EXAMPLE 4.12
main() {
const double radar_latitude = 40.7834390; //primitive double
const double radar_longitude = -73.9773670; //primitive double
const List radar_modes = const ['slow', 'medium', 'fast']; //const object
print( radar_latitude );
print( radar_longitude );
print( radar_modes );
radar_longitude += 100000; //Error – can't modify
radar_modes.add('Crazy Fast'); //Error - cannot add to an immutable list
}
Example 4.12 instantiates a List literal value at compile time by using the const keyword in conjunction with the literal syntax. This is required for declaring any non-primitive object as a constant. The const List reference is then assigned to a const identifier of radar_modes.
Unlike final variables, properties of objects that are marked as a const are immutable. You get an error when trying to use the add() method on the List constant because its values cannot be changed.
Constant Constructors
Using a const constructor allows a class of objects that cannot be defined using a literal syntax to be assigned to a constant identifier.
When using the const keyword for initialization, no matter how many times you instantiate an object with the same values, only one instance exists in memory. A constant class shares all the same instantiation restrictions as a constant object.
Class fields that are assigned using a const constructor must be marked as final. This allows new instances of the class to be instantiated by the const keyword or the new keyword.
EXAMPLE 4.13
class Location {
final int x;
final int y;
const Location(this.x, this.y);
}
main() {
const Location gate = const Location(400, 200);
const Location tower = const Location(500, 200);
const Location tube = const Location(400, 200);
//false – different values results on a new object
print(gate == tower);
//true – same class & values results in the same reference
print(gate == tube);
Location runway = new Location(400, 200);
Location tarmac = new Location(500, 200);
Location field = new Location(400, 200);
print(runway == tarmac); //false – new keyword results on a new object
print(runway == field); //false – new keyword results on a new object
}
In Example 4.13, you see that anything instantiated with the new keyword is going to create a new instance in memory, and despite matching values, these objects will be unique. You also see that objects that are created with the const keyword and that have the same values evaluate as equal objects. This is because they share the same constant object in memory.