Mutability and immutability in Dart: Understanding var, const and final

Frank Moreno
3 min readJan 9, 2022

Along years working with Dart and Flutter, one of the most repeated request change I made in pull-requests (PR) is to use final and const in the right place. This article tries to be a guide about how to use them.

Introduction

Most languages only use variables, a token that allows us to handle a set of bytes. Sometimes we do not modify the value in the memory, then why continue using variable for classify them? That’s why many languages use constants.

But what about an object that is defined once but in runtime? For this case it exists a final modifier.

Then, it is posible to propose a simplified definition for them:

  • Aconst object is defined or calculated in compile-time and allows the compiler to make some optimizations in memory.
  • A final object can not be replaced with another object in memory, and its value is defined in runtime.
  • A var object can be replaced with another object in memory.

Immutability

A memory space is immutable if it is not possible to replace the the current object with another neither updating any attribute if it’s a composed object.

By definition, a const object can not be mutated (i.e. can not be replaced with another object neither their fields can not be updated).

Here it is a questions, can a const value can be assigned to a final one?
The answer is yes, but it doesn’t make sense.

final obj = const MyClass();

obj will be only a reference to the created const value, then it can be only a const.

const obj = MyClass();

Mutability

With simple types, it is easy to understand how a memory space object is replaced with another one.

var x = 5;
x = 6; // this is possible
final y = 5;
y = 6; // syntax analyzer throws an error

But if it is an object, there is additional criteria:

var obj1 = MyClass(value: 2);
obj1.value = 3; // this is possible
final obj2 = MyClass(value: 4);
obj2.value = 5; // this is valid too
obj2 = ob1; // this is not valid because obj2 is a final objectclass MyClass {
MyClass({required this.value});
int value;
}

In addition, it is possible to assign a const value to a variable.

var x = const MyClass(1);
x = const MyClass(2); // This is possible

Memory optimization with const

The superpower of const is not visible if we use common types like int or double . To see the superpower, it is necessary to create a complex object.

The final modifier, creates and object in a new memory space despite another final object has value or fields with the same value.

But const detects if another const object contains the same value or fields with the same values, and instead of creating a new memory space, provides the reference the already created object. Thus, the compiler can optimize memory in compile-time.

That’s why you must procure use const as much as possible.

Tricks to avoid var

Sometimes if is not possible to declare some object as final because there is logic process to determine the final result.

It would be suitable to declare sum as final. Then, let’s explore some tricky solutions:

Using extension methods

For operations around an object with few others, extension methods can be a great solution.

Using self-executed-closure

When there are too many objects or there is no a main object, extension methods are not possible to use. But, an inline closure can help.

Using late final and scoped code

The closure alternative provides a good solution and can provide good tools to interrupt the code in any moment with return, but if it is not necessary, another solution is using `late final` (this is possible since null-safety feature in Dart) with scoped code.

Conclusion

We must use const as much as possible to optimize. var is necessary while the value is being edited, but it is better to have it as final after the edition stage.
In addition, final is not the same than immutable, but const is.

There are more details to explore, but now you have a panoramic vision to understand what happens with your code.

--

--

Frank Moreno

Rust, Node.js, Go and Flutter developer. I want to create tools for better developer experience with good performance.