在Dart中命名参数和位置参数之间有什么区别?

Dart支持命名可选参数和位置可选参数。两者之间有什么区别?

另外,如何判断是否实际指定了可选参数?

123149 次浏览

Dart有两种可选参数:命名位置。在讨论不同之处之前,让我先讨论一下相似之处。

Dart的可选参数是可选,因为调用者在调用函数时不需要为参数指定值。

可选参数只能声明在任何必需参数之后。

可选参数可以具有默认值,当调用方未指定值时使用该值。

位置可选参数

[ ]包装的形参是位置可选形参。这里有一个例子:

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

在上面的代码中,port是可选的,默认值为80

你可以使用或不使用第三个参数调用getHttpUrl

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

你可以为一个函数指定多个位置参数:

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

可选参数是位置,如果你想指定numRetries,你不能省略port

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

当然,除非你知道8080和5是什么,否则很难说出这些看起来很神奇的数字是什么。你可以使用命名可选参数来创建更多可读的api。

命名可选参数

{ }包装的形参是命名的可选形参。这里有一个例子:

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

你可以使用或不使用第三个参数调用getHttpUrl必须在调用函数时使用参数名。

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

你可以为一个函数指定多个命名形参:

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

因为命名形参是按名称引用的,所以它们的使用顺序可以与声明顺序不同。

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);

我相信命名参数使调用站点更容易理解,特别是当有布尔标志或脱离上下文的数字时。

检查是否提供了可选参数

不幸的是,您无法区分“未提供可选参数”和“提供默认值的可选参数”两种情况。

你可以在相同的函数或方法中使用位置可选参数命名可选参数,但不是两者都有。以下是不允许的。

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

当一个函数的形参使用“paramName: value”语法指定时,它就是一个命名形参。这些参数可以通过将它们括在[和]括号中来表示为可选的。这个函数的基本演示可以在下面的Hello World程序中演示:

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


void main() {
sayHello('Govind');
}

医生中,我们得到positionalnamed参数都是可选的,这意味着它们都可以不存在。

在我看来,named参数比positional参数更严格。例如,如果你声明这样一个方法:

String say({String from, String msg})

上面的frommsgnamed参数,当你调用方法say时,你必须使用say(from: "xx", msg: "xx")。钥匙不能没有。

但是,如果使用位置参数,则可以自由使用。

在Dart中,根据我的理解,方法参数可以给出两种类型。

  • 所需的参数
  • 可选参数(位置参数,命名为&默认)

>>必选参数

必填项参数是一个大家都很熟悉的老式参数

< em >的例子: < / em >

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


findVolume(10,20,30);

输出:< em > < / em >

length = 10, breath = 20, height = 30

>>可选位置参数

参数将用方括号[] &方括号内的参数为可选参数。

< em >例子:< / em >

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


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

输出:< em > < / em >

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

>>可选命名参数

  • 参数将用花括号{}来表示。
  • 花括号的参数是可选的。
  • 必须使用参数name分配一个用colan 分隔的值
  • 在花括号中参数的顺序并不重要
  • 这些类型形参帮助我们避免在为具有多个形参的函数传递值时产生混淆。

< em >例子:< / em >

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

输出:< em > < / em >

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

>>可选默认参数

  • 与可选命名参数一样,我们还可以为该参数指定默认值。
  • 这意味着没有传递任何值,此默认值将被接受。

< em >例子:< / em >

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

输出:< em > < / em >

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

感谢这个视频链接给出的清晰解释,感谢视频创作者。

视频链接:OptionalPositionalParameters

视频链接:OptionalNamedParameters

视频链接:OptionalDefaultParameters

位置参数:

它们与默认参数相同。例如:

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

这里y的默认值是3

命名参数:

这些参数可以以任何顺序传递,只需将参数名后跟传递的值。例如:

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

这个函数是这样调用的:

sum(num1: 12, num2: 24);

同样命名的参数也可以有默认值。

颤振例子

命名参数

Duration构造函数接受命名参数:

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

位置参数

DateTime的构造函数有1个必选位置参数和7个可选位置参数:

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

什么时候用哪个?

对于日期/时间,如果你不指定一个月,那么指定一天是没有意义的。如果我告诉你星期一,你不会知道我说的是哪一个星期一。如果指定一个月而不指定一年,这是没有意义的。枣自然地由粗变细。当然,在现实中,您会假设下周一是哪一个星期一,但是程序不能这样假设。

对于持续时间,指定哪个无关紧要。取值范围:1秒、1毫秒、5天。如果我告诉你等待5秒,我不需要告诉你0天0小时0分5秒

以下方法:

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

体重和身高为位置参数,年龄为命名参数。

我们将像下面这样调用该方法:

getBMI(65, 175, age: 35);

正如你所看到的,maned参数使呼叫站点更容易理解。