Dart Tutorial

Dart Lesson 23 of 102 2 min read

Anonymous Functions and Closures in Dart

Understand anonymous functions (lambdas) in Dart, how to store functions in variables, and how closures remember values.

On this page

In Dart a function is a value, like a number or a string. You can store it in a variable, put it in a list or pass it to another function. A function written without a name is called an anonymous function, or lambda.

Writing an anonymous function #

Take a normal function, remove the name, and you have one.

void main() {
  var numbers = [1, 2, 3];

  numbers.forEach((n) {
    print(n * 10);
  });
}
10
20
30

(n) { print(n * 10); } has parameters and a body but no name. It is created right where it is needed.

Storing a function in a variable #

void main() {
  var square = (int n) => n * n;
  int Function(int, int) add = (a, b) => a + b;

  print(square(6));
  print(add(2, 3));
}
36
5

int Function(int, int) is a function type: a function that takes two ints and returns an int.

Passing a named function by name #

You do not have to wrap an existing function in a lambda. Leave off the brackets and you pass the function itself. This is called a tear-off.

bool isLong(String word) => word.length > 4;

void main() {
  var words = ['tea', 'coffee', 'milk', 'water'];

  print(words.where(isLong).toList());
  words.forEach(print);
}
[coffee, water]
tea
coffee
milk
water

Closures #

A closure is a function that remembers the variables around it, even after the code that created those variables has finished.

Function makeCounter() {
  var count = 0;
  return () {
    count++;
    return count;
  };
}

void main() {
  var counterA = makeCounter();
  var counterB = makeCounter();

  print(counterA());
  print(counterA());
  print(counterA());
  print(counterB()); // has its own separate count
}
1
2
3
1

count is a local variable of makeCounter, yet it survives because the returned function still uses it. Each call to makeCounter creates a fresh count.

A closure that captures a parameter #

int Function(int) multiplyBy(int factor) {
  return (int value) => value * factor;
}

void main() {
  var triple = multiplyBy(3);
  var tenTimes = multiplyBy(10);

  print(triple(7));
  print(tenTimes(7));
}
21
70

Where you will see this #

  • Collection methods: list.map((x) => ...), list.where((x) => ...).
  • Event handlers in Flutter: onPressed: () { ... }.
  • Callbacks for asynchronous work: future.then((value) => ...).
  • Sorting: list.sort((a, b) => a.compareTo(b)).

Try it yourself #

Write Function makeGreeter(String greeting) that returns a function taking a name. makeGreeter('Namaste')('Asha') should return Namaste, Asha!. Create two greeters with different greetings and call each.

Practise in the playground Updated by Santosh Adhikari