Optional and Named Parameters

In Dart, you can make your functions more flexible by using optional and named parameters. This allows you to call functions with different combinations of arguments, making your code more readable and maintainable.

Positional Optional Parameters

Positional optional parameters are enclosed in square brackets []. These parameters can be omitted when calling the function, and they'll use their default values (or null if no default is provided).

void greetUser(String name, [String? greeting, int age = 18]) {
  print('$greeting $name, you are $age years old');
}

// Different ways to call the function
greetUser('Alice');                    // Hello Alice, you are 18 years old
greetUser('Bob', 'Hi');               // Hi Bob, you are 18 years old
greetUser('Charlie', 'Hey', 25);      // Hey Charlie, you are 25 years old

Named Parameters

Named parameters are enclosed in curly braces {}. They make function calls more readable because you specify the parameter name when calling the function.

void createUser({String? name, int? age, String? email}) {
  print('Creating user: $name, Age: $age, Email: $email');
}

// Call with named parameters (order doesn't matter)
createUser(name: 'Alice', age: 30, email: '[email protected]');
createUser(email: '[email protected]', name: 'Bob');
createUser(age: 25);

Required Named Parameters

You can make named parameters required by using the required keyword:

void sendEmail({required String to, required String subject, String? body}) {
  print('Sending email to: $to');
  print('Subject: $subject');
  print('Body: ${body ?? "No content"}');
}

// Must provide required parameters
sendEmail(to: '[email protected]', subject: 'Welcome!');
sendEmail(
  to: '[email protected]', 
  subject: 'Report', 
  body: 'Monthly report attached'
);

Default Values for Named Parameters

You can provide default values for named parameters:

void configureApp({
  String theme = 'light',
  bool notifications = true,
  int timeout = 30
}) {
  print('Theme: $theme');
  print('Notifications: $notifications');
  print('Timeout: ${timeout}s');
}

// Use defaults
configureApp();

// Override some defaults
configureApp(theme: 'dark', timeout: 60);

Mixing Parameter Types

You can combine positional, optional positional, and named parameters in the same function:

void processOrder(String orderId, [String? priority], {bool express = false, String? notes}) {
  print('Processing order: $orderId');
  if (priority != null) print('Priority: $priority');
  print('Express delivery: $express');
  if (notes != null) print('Notes: $notes');
}

// Different calling styles
processOrder('ORD123');
processOrder('ORD124', 'high');
processOrder('ORD125', express: true, notes: 'Handle with care');
processOrder('ORD126', 'medium', express: true);

Best Practices

ScenarioRecommendation
Few parameters (2-3)Use positional parameters
Many parametersUse named parameters for clarity
Some parameters rarely usedMake them optional
Critical parametersMake them required
Configuration-like functionsUse named parameters with defaults

Named and optional parameters make your functions more user-friendly and self-documenting. They're especially useful when you have functions with many parameters or when some parameters are only needed in specific situations.