← Flutter & Dart

Dart Fundamentals

What's the difference between `var`, `final`, and `const` in Dart?

Show answer — try answering out loud first

var declares a variable that can be reassigned. final declares a variable that is assigned exactly once at runtime. const declares a compile-time constant: its value has to be known before the program runs. The recommendation is to use final by default and const when the value is fixed at compile time.

  • var: tells Dart "infer the type for me." The value can be reassigned as many times as you want.
  • final: the variable is assigned once and can't be reassigned. The value can be computed at runtime (for example, the current time or something coming from a function).
  • const: a compile-time constant. The value must be known before the program runs, so it can't depend on anything computed at runtime.

The key difference between final and const: final is resolved when the program runs; const is resolved when it compiles. A const object is also "frozen" (it's deeply immutable), and Dart reuses it in memory (canonicalization).

Rule of thumb: use final by default. If the value is literally fixed and known at compile time, bump it up to const.

void main() {
  var counter = 0;
  counter = 1; // OK: var can be reassigned

  final name = "Mike";
  // name = "Other"; // Error: you can't reassign a final

  final now = DateTime.now(); // OK: computed at runtime
  print(now);

  const pi = 3.1416; // value known at compile time
  // const invalid = DateTime.now(); // Error: DateTime.now() is runtime

  // const freezes the contents (truly immutable)
  const list = [1, 2, 3];
  // list.add(4); // Runtime error: the list is immutable
  print(list);
}

Believing that final freezes the contents of an object. It doesn't: final only prevents reassigning the variable. A List declared with final can still mutate its contents (.add(), .remove()). For the contents to be immutable you need const.

final numbers = [1, 2, 3];
numbers.add(4); // OK: final allows mutating the contents
print(numbers); // [1, 2, 3, 4]

"var allows reassignment. final is assigned only once, but its value can be computed at runtime. const is a compile-time constant: the value has to be known before the program runs, and it also freezes the object so it's immutable. I use final by default and const when the value is fixed at compile time, like in Flutter's const constructors, which help performance."

Quick challenge

Which of these lines throws an error, and why?

final a = DateTime.now();
const b = DateTime.now();
See answer

The const b line throws an error. DateTime.now() is computed at runtime, so its value isn't known at compile time and can't be const. final a is valid because final accepts values computed at runtime.