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:

  1. mandatory (positional) arguments (only positional arguments can be mandatory)
  2. optional positional arguments
  3. (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;