What is the difference between named and positional parameters in Dart?

Dart has two types of optional parameters: named and positional. Before I discuss the differences, let me first discuss the similarities.

Dart's optional parameters are optional in that the caller isn't required to specify a value for the parameter when calling the function.

Optional parameters can only be declared after any required parameters.

Optional parameters can have a default value, which is used when a caller does not specify a value.

Positional optional parameters

A parameter wrapped by [ ] is a positional optional parameter. Here is an example:

getHttpUrl(String server, String path, [int port=80]) {
  // ...
}

In the above code, port is optional and has a default value of 80.

You can call getHttpUrl with or without the third parameter.

getHttpUrl('example.com', '/index.html', 8080); // port == 8080
getHttpUrl('example.com', '/index.html');       // port == 80

You can specify multiple positional parameters for a function:

getHttpUrl(String server, String path, [int port=80, int numRetries=3]) {
  // ...
}

The optional parameters are positional in that you can't omit port if you want to specify numRetries.

getHttpUrl('example.com', '/index.html');
getHttpUrl('example.com', '/index.html', 8080);
getHttpUrl('example.com', '/index.html', 8080, 5);

Of course, unless you know what 8080 and 5 are, it's hard to tell what those apparently magic numbers are. You can use named optional parameters to create more readable APIs.

Named optional parameters

A parameter wrapped by { } is a named optional parameter. Here is an example:

getHttpUrl(String server, String path, {int port = 80}) {
  // ...
}

You can call getHttpUrl with or without the third parameter. You must use the parameter name when calling the function.

getHttpUrl('example.com', '/index.html', port: 8080); // port == 8080
getHttpUrl('example.com', '/index.html');             // port == 80

You can specify multiple named parameters for a function:

getHttpUrl(String server, String path, {int port = 80, int numRetries = 3}) {
  // ...
}

Because named parameters are referenced by name, they can be used in an order different from their declaration.

getHttpUrl('example.com', '/index.html');
getHttpUrl('example.com', '/index.html', port: 8080);
getHttpUrl('example.com', '/index.html', port: 8080, numRetries: 5);
getHttpUrl('example.com', '/index.html', numRetries: 5, port: 8080);
getHttpUrl('example.com', '/index.html', numRetries: 5);

I believe named parameters make for easier-to-understand call sites, especially when there are boolean flags or out-of-context numbers.

Checking if optional parameter was provided

Unfortunately, you cannot distinguish between the cases "an optional parameter was not provided" and "an optional parameter was provided with the default value".

Note: You may use positional optional parameters or named optional parameters, but not both in the same function or method. The following is not allowed.

thisFunctionWontWork(String foo, [String positonal], {String named}) {
  // will not work!
}

In Dart with my understanding, method parameter can be given in two type.

  • Required parameter
  • Optional parameter (positional, named & default)

>> Required Parameter

Required parameter is a well know old style parameter which we all familiar with it

example:

findVolume(int length, int breath, int height) {
 print('length = $length, breath = $breath, height = $height');
}

findVolume(10,20,30);

output:

length = 10, breath = 20, height = 30

>> Optional Positional Parameter

parameter will be disclosed with square bracket [ ] & square bracketed parameter are optional.

example:

findVolume(int length, int breath, [int height]) {
 print('length = $length, breath = $breath, height = $height');
}

findVolume(10,20,30);//valid
findVolume(10,20);//also valid

output:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = null // no value passed so height is null

>> Optional Named Parameter

  • parameter will be disclosed with curly bracket { }
  • curly bracketed parameter are optional.
  • have to use parameter name to assign a value which separated with colan :
  • in curly bracketed parameter order does not matter
  • these type parameter help us to avoid confusion while passing value for a function which has many parameter.

example:

findVolume(int length, int breath, {int height}) {
 print('length = $length, breath = $breath, height = $height');
}

findVolume(10,20,height:30);//valid & we can see the parameter name is mentioned here.
findVolume(10,20);//also valid

output:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = null

>> Optional Default Parameter

  • same like optional named parameter in addition we can assign default value for this parameter.
  • which means no value is passed this default value will be taken.

example:

findVolume(int length, int breath, {int height=10}) {
 print('length = $length, breath = $breath, height = $height');
} 

findVolume(10,20,height:30);//valid
findVolume(10,20);//valid 

output:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = 10 // default value 10 is taken

thanks for the clear explanation given from this video link, credits to the video creator.

video link : OptionalPositionalParameters

video link : OptionalNamedParameters

video link : OptionalDefaultParameters


Positional Parameters:

They are same as default parameters. For example:

void add(int x, [int y = 3]);

Here y has the default value of 3

Named Parameters:

These are parameters that can be passed in any order by passing the name of the parameter followed by the passed value. For example:

void sum({int num1, int num2});

This function is called like this:

sum(num1: 12, num2: 24);

Also named parameters can also have default values.


Dart has two kinds of function parameters: positional and named.

Optional positional parameters

Positional parameters are the kind you’re likely familiar with:

int sumUp(int a, int b, int c) {
  return a + b + c;
}
// ···
  int total = sumUp(1, 2, 3);

With Dart, you can make these positional parameters optional by wrapping them in brackets:

int sumUpToFive(int a, [int b, int c, int d, int e]) {
  int sum = a;
  if (b != null) sum += b;
  if (c != null) sum += c;
  if (d != null) sum += d;
  if (e != null) sum += e;
  return sum;
}
// ···
  int total = sumUpToFive(1, 2);
  int otherTotal = sumUpToFive(1, 2, 3, 4, 5);

Optional positional parameters are always last in a function’s parameter list. Their default value is null unless you provide another default value:

int sumUpToFive(int a, [int b = 2, int c = 3, int d = 4, int e = 5]) {
// ···
}
// ···
  int newTotal = sumUpToFive(1);
  print(newTotal); // <-- prints 15

Code example

Implement a function called joinWithCommas() that accepts one to five integers, then returns a string of those numbers separated by commas. Here are some examples of function calls and returned values:

String joinWithCommas(int a, [int b, int c, int d, int e]) {
  var total = '$a';
  if (b != null) total = '$total,$b';
  if (c != null) total = '$total,$c';
  if (d != null) total = '$total,$d';
  if (e != null) total = '$total,$e';
  return total;
}

Function call

joinWithCommas(1)       
joinWithCommas(1, 2, 3)     
joinWithCommas(1, 1, 1, 1, 1)

Returned value

'1'
'1,2,3'
'1,1,1,1,1'

Optional named parameters

Using a curly brace syntax, you can define optional parameters that have names.

void printName(String firstName, String lastName, {String suffix}) {
  print('$firstName $lastName ${suffix ?? ''}');
}
// ···
  printName('Avinash', 'Gupta');
  printName('Poshmeister', 'Moneybuckets', suffix: 'IV');

As you might expect, the value of these parameters is null by default, but you can provide default values:

void printName(String firstName, String lastName, {String suffix = ''}) {
  print('$firstName $lastName $suffix');
}

A function can’t have both optional positional and optional named parameters.

Code example

Add a copyWith() instance method to the MyDataObject class. It should take three named parameters:

int newInt
String newString
double newDouble

When called, copyWith() should return a new MyDataObject based on the current instance, with data from the preceding parameters (if any) copied into the object’s properties. For example, if newInt is non-null, then copy its value into anInt.

class MyDataObject {
  final int anInt;
  final String aString;
  final double aDouble;

  MyDataObject({
     this.anInt = 1,
     this.aString = 'Old!',
     this.aDouble = 2.0,
  });

  // Add your copyWith method here:
}