Functions and parameters

Dart · Essentials · 10 min

Named parameters are everywhere in Flutter, and functions as values drive callbacks and collection methods.

A function declares its return type, name and parameters: int add(int a, int b) { return a + b; }. For a single expression, use arrow syntax: int add(int a, int b) => a + b;.

Parameter kinds:

  • Required positional: f(int a).
  • Optional positional in brackets: f(int a, [int b = 0]).
  • Named in braces: f({required String name, int age = 0}). Callers write f(name: 'Ana'). Named parameters are optional unless marked required; optional ones need a default or a nullable type.

You can't mix optional positional and named parameters in the same function. Flutter APIs use named parameters almost everywhere because they read clearly: Padding(padding: ..., child: ...).

Functions are objects. You can assign them to variables, pass them as arguments and return them. Their types are written like int Function(int, int). Anonymous functions look like (x) => x * 2 or (x) { ... }.

A function that refers to variables from its surrounding scope is a closure; it keeps those variables alive and sees later changes.

typedef Compare = int Function(String a, String b); gives a function type a name. Top-level functions, static methods and instance methods (tear-offs like list.add) can all be passed where a function is expected.

Example

String greet(String name, {String greeting = 'Hello', bool shout = false}) {
  final text = '$greeting, $name';
  return shout ? text.toUpperCase() : text;
}
int power(int base, [int exponent = 2]) {
  var result = 1;
  for (var i = 0; i < exponent; i++) result *= base;
  return result;
}

int Function() makeCounter() {
  var count = 0;
  return () => ++count;            // closure over count
}

void main() {
  print(greet('Ana'));                       // Hello, Ana
  print(greet('Bo', shout: true, greeting: 'Hi'));  // HI, BO
  print('${power(3)} ${power(2, 10)}');      // 9 1024

  final next = makeCounter();
  next();
  print(next());                             // 2
  print([1, 2, 3].map((x) => x * 10).toList());  // [10, 20, 30]
}

Remember

  • Named params {...} are optional unless required
  • => is shorthand for a one-expression body
  • Functions are values; closures capture variables

Watch out for

  • Forgetting required on a non-nullable named parameter without a default, which is a compile error.

Check yourself

  1. Given `void f(int a, {int b = 1})`, which call is valid?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: dart.dev/language/functions