284

Dart supports both named optional parameters and positional optional parameters. What are the differences between the two?

Also, how can you tell if an optional parameter was actually specified?

Seth Ladd
  • 112,095
  • 66
  • 196
  • 279
  • Case optional named parameters - I am using dart class in flutter and code is as: class MyDataObject { final int anInt; final String aString; final double aDouble; MyDataObject({ this.anInt = 1, this.aString = 'Old!', this.aDouble = 2.0, }); } getting error that need to 'Add required keyword' before this.anInt = 1, this.aString = 'Old!' and this.aDouble = 2.0, Kindly suggest what is the issue and how can we fix it. Thanks. – Kamlesh May 25 '21 at 03:33

7 Answers7

519

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!
}
onmyway133
  • 45,645
  • 31
  • 257
  • 263
Seth Ladd
  • 112,095
  • 66
  • 196
  • 279
  • 4
    ? operator has been deprecated. I've found only scale==null condition in dart tutorial. (expr1 ? expr2 : expr3 still works) – Zdeněk Mlčoch Nov 29 '13 at 23:46
  • 2
    Loving the multiple named params for a function, this was hard to find! Would look even better in the constructors part of docs? ;) – Will Squire Dec 10 '14 at 20:50
  • 2
    Default values should now be specified with `=` instead of `:`, according to https://www.dartlang.org/guides/language/language-tour#optional-positional-parameters. – nbro Aug 14 '17 at 17:26
  • 7
    Why can't we use both positional optional parameters and named optional parameters. – Donghua Liu Sep 16 '20 at 15:26
  • Historically, which one was first implemented by Dart Team, "positional" or "named" optional parameters? My conjecture: The first implemented one is positional optional parameters. – Second Person Shooter Oct 12 '20 at 15:29
  • Case optional named parameters - I am using dart class in flutter and code is as: class MyDataObject { final int anInt; final String aString; final double aDouble; MyDataObject({ this.anInt = 1, this.aString = 'Old!', this.aDouble = 2.0, }); } getting error that need to 'Add required keyword' before this.anInt = 1, this.aString = 'Old!' and this.aDouble = 2.0, Kindly suggest what is the issue and how can we fix it. Thanks. – Kamlesh May 25 '21 at 03:33
  • 4
    Just to be clear, you can require named parameters by using the required keyword, e.g.: {required String name} – CoderBlue Jun 10 '21 at 15:01
63

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

SaravanaRaja
  • 3,228
  • 2
  • 21
  • 29
  • Case optional named parameters - I am using dart class in flutter and code is as: class MyDataObject { final int anInt; final String aString; final double aDouble; MyDataObject({ this.anInt = 1, this.aString = 'Old!', this.aDouble = 2.0, }); } getting error that need to 'Add required keyword' before this.anInt = 1, this.aString = 'Old!' and this.aDouble = 2.0, Kindly suggest what is the issue and how can we fix it. Thanks. – Kamlesh May 25 '21 at 03:32
  • Need your suggestion for Null Safety. Thanks. – Kamlesh May 25 '21 at 03:43
  • That was great simple and precise thanks a lot – Aghiad Alzein Aug 23 '21 at 08:07
7

When the parameter of a function is specified using "paramName : value" syntax, then it is a named parameter. Such parameters can be rendered optional by enclosing them between [ and ] brackets. A rudimentary demonstration of this function can be demonstrated in the following Hello World program:

sayHello([String name = ' World!']) {
  print('Hello, ${name}');
}

void main() {
  sayHello('Govind');
}
Balepur
  • 138
  • 1
  • 7
7

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.

Zohaib Hamdule
  • 540
  • 9
  • 23
6

Examples from Flutter

Named arguments

The Duration class constructor takes named parameters:

const Duration(
{int days = 0,
int hours = 0,
int minutes = 0,
int seconds = 0,
int milliseconds = 0,
int microseconds = 0}
)

Positional arguments

The DateTime class's constructor has 1 required positional argument, and 7 optional positional arguments:

DateTime(
int year,
[int month = 1,
int day = 1,
int hour = 0,
int minute = 0,
int second = 0,
int millisecond = 0,
int microsecond = 0]
)

When to use which?

For dates/ times, it doesn't make sense to specify a day if you don't specify a month. If I told you Monday, you wouldn't know which Monday I was talking about. It doesn't make sense if you specify a month but don't specify a year. Dates naturally go from coarse to fine. Of course, in reality you would assume which Monday would be next monday, but programs can't assume this.

For Duration, it doesn't matter which you specify. A Duration of time can be 1 second, or 1 millisecond, or 5 days. If I told you wait 5 seconds, I don't need to tell you 0 days, 0 hours, 0 minutes and 5 seconds.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
5

From doc we get that both positional and named parameters are optional, which means they all can be absent.

In my opinion, named parameters are more strict than positional ones. For example, if you declare such a method:

String say({String from, String msg})

Above from and msg are named parameters, when you call method say you must use say(from: "xx", msg: "xx"). The keys cannot be absent.

However if you use positional parameters, you are free.

kalucki23
  • 172
  • 4
  • 15
CoXier
  • 2,523
  • 8
  • 33
  • 60
  • 1
    The doc says: > Optional parameters can be either named or positional, but not both. Where does it say that positional parameters are optional? – Markon Aug 15 '19 at 21:55
  • A positional parameter is the default style of parameters in programming languages, called positional because "it's the first parameter, or second, etc". `Named` parameters are called like that because you can actually identify them by name and not by position (if you switch the position of two named params, it doesn't matter). See the answer above from Savaranaraja – Markon Aug 15 '19 at 21:57
0

In the below method:

getBMI(float weight, float height, {int age = 80}) {
  // method body
}

weight and height are positional parameters, and age is named parameter.

We will call the method like below:

getBMI(65, 175, age: 35);

As you can see maned parameters make for easier-to-understand call sites.

Fakhriddin Abdullaev
  • 4,169
  • 2
  • 35
  • 37