Optional and Named Parameters
Making parameters optional, giving them default values, and calling functions with named arguments for clarity.
អាន 2 នាទី
Real functions often need parameters that aren't always required, or that read better labeled at the call site than positioned by order alone. Dart supports both directly in the language, rather than forcing you to fake them with overloads or config objects.
Positional optional parameters
Wrapping parameters in square brackets [] makes them optional. Callers can omit them, in which case they're null unless you give a default:
String buildGreeting(String name, [String? title, String greeting = 'Hello']) {
final prefix = title != null ? '$title ' : '';
return '$greeting, $prefix$name!';
}
print(buildGreeting('Sokha')); // Hello, Sokha!
print(buildGreeting('Sokha', 'Dr.')); // Hello, Dr. Sokha!
print(buildGreeting('Sokha', 'Dr.', 'Welcome')); // Welcome, Dr. Sokha!title has no default, so its type must be nullable (String?) to legally be left out. greeting has a default value ('Hello'), so it stays non-nullable — if the caller skips it, Dart substitutes the default rather than null.
Named parameters
Wrapping parameters in curly braces {} makes them named — callers pass them as label: value, in any order, which is far more readable once a function takes more than two or three arguments:
void createUser({required String name, required int age, String? email}) {
print('$name, $age${email != null ? ', $email' : ''}');
}
void main() {
createUser(name: 'Dara', age: 28);
createUser(age: 34, name: 'Lina', email: 'lina@example.com');
}required marks a named parameter as mandatory — omit it, and the analyzer flags the call as an error before you ever run the program. Without required, a named parameter must either be nullable or have a default value, for the same reason positional optional parameters do: Dart won't let a non-nullable value silently become null.
Combining them
A function can mix required positional parameters with either optional positional or named parameters, but not both bracket styles at once:
double calculateTotal(double price, {double taxRate = 0.1, double discount = 0}) {
final discounted = price - discount;
return discounted + (discounted * taxRate);
}
print(calculateTotal(100)); // 110.0
print(calculateTotal(100, discount: 20)); // 88.0
print(calculateTotal(100, taxRate: 0.05, discount: 10)); // 94.5Why named parameters matter in practice
Compare Container(200, 100, Colors.blue, 8) to Container(width: 200, height: 100, color: Colors.blue, borderRadius: 8) — the second tells you what each number means without needing to check the function's signature. This is exactly why Flutter's widget constructors lean almost entirely on named parameters: with a dozen optional settings, positional order would be unreadable and error-prone. The habit is worth adopting in your own functions well before you ever touch Flutter.