Dart支持命名可选参数和位置可选参数。两者之间有什么区别?
另外,如何判断是否实际指定了可选参数?
Dart支持命名可选参数和位置可选参数。两者之间有什么区别?
另外,如何判断是否实际指定了可选参数?
当前回答
从doc中我们得到位置形参和命名形参都是可选的,这意味着它们都可以不存在。
在我看来,命名参数比位置参数更严格。例如,如果你声明这样一个方法:
String say({String from, String msg})
上面的from和msg是命名参数,当你调用方法say时,你必须使用say(from: "xx", msg: "xx")。钥匙不能没有。
但是,如果使用位置参数,则可以自由使用。
其他回答
Dart有两种可选参数:named和positional。在讨论不同之处之前,让我先讨论一下相似之处。
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!
}
颤振例子
命名参数
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]
)
什么时候用哪个?
对于日期/时间,如果不指定月份,那么指定一天是没有意义的。如果我告诉你星期一,你不会知道我说的是哪一个星期一。如果指定一个月而不指定一年,这是没有意义的。枣自然地由粗变细。当然,在现实中,您会假设下周一是哪一个星期一,但是程序不能这样假设。
对于Duration,指定哪个无关紧要。取值范围:1秒、1毫秒、5天。如果我告诉你等5秒,我不需要告诉你0天0小时0分5秒。
以下方法:
getBMI(float weight, float height, {int age = 80}) {
// method body
}
体重和身高为位置参数,年龄为命名参数。
我们将像下面这样调用该方法:
getBMI(65, 175, age: 35);
正如你所看到的,maned参数使呼叫站点更容易理解。
当一个函数的形参使用“paramName: value”语法指定时,它就是一个命名形参。这些参数可以通过将它们括在[和]括号中来表示为可选的。这个函数的基本演示可以在下面的Hello World程序中演示:
sayHello([String name = ' World!']) {
print('Hello, ${name}');
}
void main() {
sayHello('Govind');
}
从doc中我们得到位置形参和命名形参都是可选的,这意味着它们都可以不存在。
在我看来,命名参数比位置参数更严格。例如,如果你声明这样一个方法:
String say({String from, String msg})
上面的from和msg是命名参数,当你调用方法say时,你必须使用say(from: "xx", msg: "xx")。钥匙不能没有。
但是,如果使用位置参数,则可以自由使用。