What do curly braces wrapping constructor arguments represent?
Consider the following piece of code:
class Person {
String id;
String name;
ConnectionFactory connectionFactory;
// What is this constructor doing?
Person({this.connectionFactory: _newDBConnection});
}
If you precede a constructor's argument with this
, the corresponding field will be automatically initialized, but why {...}
?
This makes the argument a named optional argument.
When you instantiate a Person
you can
Person p;
p = new Person(); // default is _newDbConnection
p = new Person(connectionFactory: aConnectionFactoryInstance);
- without
{}
the argument would be mandatory - with
[]
the argument would be an optional positional argument
// Constructor with positional optional argument
Person([this.connectionFactory = _newDBconnection]);
...
Person p;
p = new Person(); // same as above
p = new Person(aConnectionFactoryInstance); // you don't specify the parameter name
Named optional parameters are very convenient for boolean arguments (but of course for other cases too).
p = new Person(isAlive: true, isAdult: false, hasCar: false);
There is a specific order in which these argument types can be used:
- mandatory (positional) arguments (only positional arguments can be mandatory)
- optional positional arguments
- (optional) named arguments (named arguments are always optional)
Note that positional and named optional arguments use a different delimiter for the default value.
The named requires :
but the positional requires =
. The language designers argue that the colon fits better with the Map literal syntax (I would at least have used the same delimiter for both).
=
is supported as delimiter since Dart 2 and preferred according to the style guide while :
is still supporzed.
See also:
- What is the difference between named and optional parameters in Dart?
- Functions Are Fun, Pt 1 - Dart Tips, Ep 6
- Chapter 2. A Tour of the Dart Language - Functions
- Chapter 2. A Tour of the Dart Language - Constructors
Dart functions allow positional parameters, named parameters, and optional positional and named parameters, or a combination of all of them.
Positional parameters are simply without decoration:
void debugger(String message, int lineNum) {
// ...
}
Named parameters means that when you call a function, you attach the argument to a label. This example calls a function with two named parameters:
debugger(message: 'A bug!', lineNum: 44);
Named parameters are written a bit differently. You wrap any named parameters in curly braces ({ })
. This line defines a function with named parameters:
void debugger({String message, int lineNum}) {
Named parameters, by default, are optional. But you can annotate them and make them required:
Widget build({@required Widget child}) {
//...
}
Finally, you can pass positional parameters that are optional, using [ ]
:
int addSomeNums(int x, int y, [int z]) {
int sum = x + y;
if (z != null) {
sum += z;
}
return sum;
}
You call that function like this:
addSomeNums(5, 4)
addSomeNums(5, 4, 3)
You can define default values for parameters with the =
operator in the function signature, and the function can be simplified as below:
addSomeNums(int x, int y, [int z = 5]) => x + y + z;