Classes, Enums, Extensions
Immutable Data
final fields and const constructors
An immutable data object pairs final fields with a const constructor. Each instance is frozen after construction, and the constructor can also be used in const contexts. A small method that reads the fields keeps presentation logic with the data.
Program
Play the program to build two Todo values and print their labels.
immutable_pattern.dart
Replay: real traced execution (multi-file project)
class Todo {
final String title;
final bool done;
const Todo(this.title, {this.done = false});
String label() => '[${done ? 'x' : ' '}] $title';
}
void main() {
final a = Todo('Write notes', done: true);
final b = Todo('Buy milk');
print('${a.label()} | ${b.label()}');
}
a ← constructing Todo('Write notes', done: true)
8void main() {9 final a = Todo('Write notes', done: true);10 final b = Todo('Buy milk');values this stepconstructing Todo('Write notes', done: true)afields ← title=Write notes, done=true
3final bool done;4const Todo(this.title, {this.done = false});5String label() => '[${done ? 'x' : ' '}] $title';values this steptitle=Write notes, done=truefieldsa ← Todo(title: Write notes, done: true)
8void main() {9 final a = Todo('Write notes', done: true);10 final b = Todo('Buy milk');values this stepTodo(title: Write notes, done: true)ab ← constructing Todo('Buy milk')
9final a = Todo('Write notes', done: true);10final b = Todo('Buy milk');11print('${a.label()} | ${b.label()}');values this stepconstructing Todo('Buy milk')bfields ← title=Buy milk, done=false
3final bool done;4const Todo(this.title, {this.done = false});5String label() => '[${done ? 'x' : ' '}] $title';values this steptitle=Buy milk, done=falsefieldsb ← Todo(title: Buy milk, done: false)
9final a = Todo('Write notes', done: true);10final b = Todo('Buy milk');11print('${a.label()} | ${b.label()}');values this stepTodo(title: Buy milk, done: false)breturn ← [x] Write notes
4 const Todo(this.title, {this.done = false});5 String label() => '[${done ? 'x' : ' '}] $title';6}values this step[x] Write notesreturntruedoneWrite notestitlereturn ← [ ] Buy milk
4 const Todo(this.title, {this.done = false});5 String label() => '[${done ? 'x' : ' '}] $title';6}values this step[ ] Buy milkreturnfalsedoneBuy milktitleprint('${a.label()} | ${b.label()}');
10 final b = Todo('Buy milk');11 print('${a.label()} | ${b.label()}');12}output[x] Write notes | [ ] Buy milkvalues this step[x] Write notesa.label()[ ] Buy milkb.label()
final fields
`final String title; final bool done;` freeze the values after construction.
const constructor
`const Todo(this.title, {this.done = false});` supports ordinary construction here and also allows compile-time constants when called with `const`.
named default
`{this.done = false}` gives the named parameter a default; `Todo('Buy milk')` omits it.