What is the difference between the const
and final
keywords in Dart?
There is a post on dart's website and it explains it pretty well.
Final:
"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.
Const:
"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.
Const objects have a couple of interesting properties and restrictions:
They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.
They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.
They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated.
So, what does this mean?
Const:
If the value you have is computed at runtime (new DateTime.now()
, for example), you can not use a const for it. However, if the value is known at compile time (const a = 1;
), then you should use const
over final
. There are 2 other large differences between const
and final
. Firstly, if you're using const
inside a class, you have to declare it as static const
rather than just const
. Secondly, if you have a const
collection, everything inside of that is in const
. If you have a final
collection, everything inside of that is not final
.
Final:
final
should be used over const
if you don't know the value at compile time, and it will be calculated/grabbed at runtime. If you want an HTTP response that can't be changed, if you want to get something from a database, or if you want to read from a local file, use final
. Anything that isn't known at compile time should be final
over const
.
With all of that being said, both const
and final
cannot be reassigned, but fields in a final
object, as long as they aren't const
or final
themselves, can be reassigned (unlike const
).
void main() { var fruits = ['apples', 'bananas', 'oranges']; for ( final fruit in fruits) { print('I like to eat $fruit'); } }
Will it print always the same? –
Abagael final
is like const
in js –
Davisdavison var
(as a bonus). –
Factory Const
Value must be known at compile-time, const birthday = "2008/12/25"
Can't be changed after initialized.
Final
Value must be known at run-time, final birthday = getBirthDateFromDB()
Can't be changed after initialized.
final
variables can't be reassigned, but the object can be mutated. –
Wonderwork final
object cannot be modified but its fields can be changed. dartpad.dartlang.org/?id=2078935ac3ac4fcb26e8f8e53b250889 –
Zel Consolidated @Meyi and @faisal-naseer answers and Comparing with little programming.
const:
const keyword used to make a variable to store a compile time constant value. Compile time constant value is a value which will be constant while compiling :-)
For example 5
is a compile time constant. While DateTime.now()
which is not compile time constant. Because this method will return the time when the line is getting executed at runtime. So we can't assign the DateTime.now()
to a const
variable.
const a = 5;
// Uncommenting below statement will cause compile time error.
// Because we can't able to assign a runtime value to a const variable
// const b = DateTime.now();
Should be initialized at the same line.
const a = 5;
// Uncommenting below 2 statement will cause compilation error.
// Because const variable must be initialized at the same line.
// const b;
// b = 6;
All statements mentioned below are acceptable.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// Uncommenting the below line causes a compilation error. Cause const can't be used with var.
// const var c = 6;
Class level const variable should be initialized like below.
Class A {
static const a = 5;
}
Instance level const variable is not possible.
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
The another major use of const
is used to make the object immutable. To make a class object immutable we need to use the const keyword with constructor and make all the fields as final like mentioned below.
Class A {
final a, b;
const A(this.a, this.b);
}
void main () {
// There is no way to change a field of object once it's
// initialized.
const immutableObja = const A(5, 6);
// Uncommenting below statement will give compilation error.
// Because you are trying to reinitialize a const variable
// with other value
// immutableObja = const A(7, 9);
// But the below one is not the same. Because we are mentioning objA
// is a variable of a class A. Not const. So we can able to assign
// another object of class A to objA.
A objA = const A(8, 9);
// Below statement is acceptable.
objA = const A(10, 11);
}
we can use const keyword to a list.
const a = const [] - A variable a
initialized as const
which contains a list of const
objects(i.e., The list should contain only compile time constant and immutable objects). So we can't able to assign a
with another list.
var a = const [] - A variable a
initialized as var
which contains a list const
objects. So we can able to assign another list to the variable a
.
Class A {
final a, b;
const A(this.a, this.b);
}
class B {
B(){ // Doing something }
}
void main() {
const constantListOfInt = const [5, 6, 7,
// Uncommenting below statement give compilation error.
// Because we are trying to add a runtime value
// to a constant list
// DateTime.now().millisecondsSinceEpoch
];
const constantListOfConstantObjA = const [
A(5, 6),
A(55, 88),
A(100, 9),
];
// Uncommenting below 2 statements will give compilation error.
// Because we are trying to reinitialize with a new list.
// constantListOfInt = [8, 9, 10];
// constantListOfConstantObjA = const[A(55, 77)];
// But the following lines are little different. Because we are just
// trying to assign a list of constant values to a variable. Which
// is acceptable
var variableWithConstantList = const [5, 6, 7];
variableWithConstantList = const [10, 11, 15];
var variableOfConstantListOfObjA = const [A(5, 8), A(7, 9), A(10, 4)];
variableWithConstantList = const [A(9, 10)];
}
final:
final keyword also used to make the variable to hold a constant value. Once initialized we can't change the value.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
All statements mentioned below are acceptable.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// Can't use var along with final keyword. Uncommenting below line cause compilation issue.
// final var c = 6;
Able to assign a runtime value.
// DateTime.now() will return the time when the line is getting
// executed. Which is a runtime value.
final a = DateTime.now();
var b = 5;
final c = b;
Class level final variable must be initialized in the same line.
Class A {
static final a = 5;
static final b = DateTime.now();
}
Instance level final variable must be initialized in the same line or in the constructor initialization. The value will be put into memory when the object is created.
Class A {
final a = 5;
}
// Constructor with a parameter.
Class B {
final b;
B(this.b);
}
// Constructor with multiple parameter.
Class C {
final c;
C(this.c, int d) {
// Do something with d
}
}
void main() {
A objA = new A();
B objB = new B(5);
C objC = new C(5, 6);
}
Assigning a list.
final a = [5, 6, 7, 5.6, A()];
// Uncommenting Below statement will give compilation error.
// Because we are trying to reinitialize the object with another list.
// a = [9.9, 10, B()];
const immutableObja = const A(5, 6);
can also be written as const immutableObja = A(5, 6);
because const A(5,6)
rather than new A(5,6)
will be chosen by the smart Dart compiler. –
Gimble final var c = 6;
is not allowed. Members declared cannot be declared to be both final
and var
. –
Wellfounded const var c = 6;
is not acceptable on dart 2.19.6 –
Terle Extending the answer by @Meyi
- final variable can only be set once and it is initialized when
accessed.(for example from code section below if you use the value of
biggestNumberOndice
only then the value will be initialized and memory will be assigned). const is internally final in nature but the main difference is that its compile time constant which is initialized during compilation even if you don't use its value it will get initialized and will take space in memory.
Variable from classes can be final but not constant and if you want a constant at class level make it static const.
Code:
void main() {
// final demonstration
final biggestNumberOndice = '6';
// biggestNumberOndice = '8'; // Throws an error for reinitialization
// const
const smallestNumberOnDice = 1;
}
class TestClass {
final biggestNumberOndice = '6';
//const smallestNumberOnDice = 1; //Throws an error
//Error . only static fields can be declared as constants.
static const smallestNumberOnDice = 1;
}
const
means its initial value is must be fixed, can not be a dynamic value;
final
means its initial value is must be fixed but can be a dynamic value, equal to the var
with a fixed value.
code demos
const
void main() {
const sum = 1 + 2;
// ✅ const can not change its value
print("sum = ${sum}");
// ⚠️ Const variables must be initialized with a constant value.
const time = new DateTime.now();
// ❌ Error: New expression is not a constant expression.
print("time = ${time}");
}
final
// new DateTime.now();
// dynamic timestamp
void main() {
final sum = 1 + 2;
// ✅ final can not change its value
print("sum = ${sum}");
final time = new DateTime.now();
// ✅ final === var with fixed value
print("time = ${time}");
}
Screenshots
refs
https://dart.dev/guides/language/language-tour#final-and-const
final
and const
in dart are confusing to the level we think both of them are the same.
Let's see their differences :
P.S. I included image instead of text as I couldn't tabulate the info in Stackoverflow .md format easily.
Anything that isn't known at compile time should be final
over const
.
Both final
and const
prevent a variable from being reassigned (similar to how final
works in Java or how const
works in JavaScript).
The difference has to do with how memory is allocated. Memory is allocated for a final
variable at runtime, and for a const
variable at compile-time. The final
modifier should be the more commonly used, because many program variables won't need any memory since the program logic won't call for them to be initialized. With a const
variable you are basically telling the computer, "Hey, I need memory for this variable up front because I know I'm going to need it."
Thinking of them in this way makes it easier to understand differences in their syntactical usage. Mainly that a final
variable may be an instance variable, but a const
must be a static
variable on a class. This is because instance variables are created at runtime, and const
variables--by definition--are not. Thus, const
variables on a class must be static
, which means simply that a single copy of that variable exists on a class, regardless of whether that class is instantiated.
This video breaks it down fairly simply: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
This article goes into more depth and explains a very important semantic difference between the two, i.e. final
modifies variables and const
modifies values, which essentially boils down to only being able to initialize const
values which are derivable at compile-time.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
If you are coming from C++
then const
in Dart
is constexpr
in C++
and final
in Dart
is const
in C++
.
The above applies to primitive types only.
However in Dart
objects marked final
are mutable in terms of it's members.
const
in C++ is almost always used to specify that an object is not mutable through a specific reference or pointer. final
in Dart does not prevent the object from being mutated through that variable. –
Wonderwork Simple words:
Const
Value must be known at compile-time, i.e. values coming from internal files.
Sample: API keys, supported languages of your app or any variables in your i.e. helper file, basically anything which you ship with your app.
Final
Value must be known at run-time.
It can be data like above but also i.e. device info which will be checked when the app is starting or data that is loaded from API's or servers when the app starts, but before the app is ready to use i.e. you need to check if the user is logged in or not, your app would load or check a session token from the server.
All these answers I can describe in a concise way.
const list = [1, 2, 3];
- Both variable/identifier & value are const. Like -
const list = const [1, 2, 3]
- That's why they are not allowed to be re-assigned.
- Good fit for global variables.
- It is possible to use it as a class variable but have to set static. Like -
static const list = [1, 2, 3]
.
vs:
final list = [1, 2, 3];
- Variable/Identifier is const but value is not. Like -
const list = [1, 2, 3]
- That's why we can perform like -
list.add(4)
const
is a Compile-time constant.
final
is a Run-time constant.
final
variables cannot be reassigned but the object can be mutated. They are not runtime constants. –
Wonderwork You can't initialise a const
using a final
. For example :
final myConst = 1;
const myFinal = 2;
final a = myConst; // possible
final b = myFinal; // possible
const c = myConst; // this is not possible
const d = myFinal; // possible
const
and final
mean. Also, that you named the const
object myFinal
and the final
variable myConst
is very confusing. –
Wonderwork When to use which keyword?
A simple example for both: Use final: If you don’t know what it’s value will be at compile-time. For example, when you can need to get data from an API, this happens when running your code.
Use const: If you are sure that a value isn’t going to be changed when running your code. For example, when you declare a sentence that always remains the same.
https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573
A variable with the final
keyword will be initialized at runtime and can only be assigned for a single time.
A variable with the const
keyword is initialized at compile-time and is already assigned when at runtime.
Use final
: If you don’t know what it’s value will be at compile-time. For example, when you can need to get data from an API, this happens when running your code.
Use const
: If you are sure that a value isn’t going to be changed when running your code. For example, when you declare a sentence that always remains the same.
Well, an unofficial but easy way to understand:
- Compile time: when you're coding
- Run time: when you run the application
So to be short,
final
: as long as in run time it's a constant. Its value is not needed in compile time, assign but decide later ie.DatTime.now()
const
: if a value is known and will be the same for both compile and run time. A value always the same ie.int 10
both value of final
and const
cannot be changed in the future (in run time)
© 2022 - 2024 — McMap. All rights reserved.
const
: #51576709 and the simple explonation tofinal
is constant(cannot reassign or assign once created with final keyword) and you have to initialize it once. – Stuffy