What do curly braces wrapping constructor arguments represent?

Dart

Dart Problem Overview


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 {...}?

Dart Solutions


Solution 1 - Dart

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:

Solution 2 - Dart

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;

Solution 3 - Dart

the this. connectionFactory in

Person({this.connectionFactory: _newDBConnection});

is called Automatic Class Member Variable Initialization. See this example

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLiglo AppView Question on Stackoverflow
Solution 1 - DartGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - DartX. WangView Answer on Stackoverflow
Solution 3 - DartFelixView Answer on Stackoverflow