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

Set*_*add 105 dart

Dart支持命名的可选参数和位置可选参数.两者有什么不同?

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

Set*_*add 201

Dart有两种可选参数:命名位置.在讨论差异之前,让我先讨论相似之处.

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

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

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

位置可选参数

包装的参数[ ]是位置可选参数.这是一个例子:

getHttpUrl(String server, String path, [int port=80]) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

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

您可以getHttpUrl使用或不使用第三个参数进行调用.

getHttpUrl('example.com', '/index.html', 8080); // port == 8080
getHttpUrl('example.com', '/index.html');       // port == 80
Run Code Online (Sandbox Code Playgroud)

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

getHttpUrl(String server, String path, [int port=80, int numRetries=3]) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

可选参数是位置的,port如果要指定,则不能省略numRetries.

getHttpUrl('example.com', '/index.html');
getHttpUrl('example.com', '/index.html', 8080);
getHttpUrl('example.com', '/index.html', 8080, 5);
Run Code Online (Sandbox Code Playgroud)

当然,除非你知道8080和5是什么,否则很难说这些神奇的数字是什么.您可以使用命名的可选参数来创建更具可读性的API.

命名可选参数

包装的参数{ }是命名的可选参数.这是一个例子:

getHttpUrl(String server, String path, {int port = 80}) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

您可以getHttpUrl使用或不使用第三个参数进行调用.你必须调用函数时使用的参数名称.

getHttpUrl('example.com', '/index.html', port: 8080); // port == 8080
getHttpUrl('example.com', '/index.html');             // port == 80
Run Code Online (Sandbox Code Playgroud)

您可以为函数指定多个命名参数:

getHttpUrl(String server, String path, {int port = 80, int numRetries = 3}) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

由于命名参数是按名称引用的,因此可以按与其声明不同的顺序使用它们.

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);
Run Code Online (Sandbox Code Playgroud)

我相信命名参数有助于更容易理解的调用站点,特别是当有布尔标志或超出上下文的数字时.

检查是否提供了可选参数

遗憾的是,您无法区分"未提供可选参数"和"使用默认值提供可选参数"的情况.

注意:您可以使用位置可选参数命名可选参数,但不能同时使用相同的函数或方法.以下是不允许的.

thisFunctionWontWork(String foo, [String positonal], {String named}) {
  // will not work!
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么我们不能同时使用位置可选参数和命名可选参数。 (7认同)
  • ?运算符已被弃用.我在dart教程中发现只有scale == null条件.(expr1?expr2:expr3仍然有效) (4认同)
  • 需要明确的是,您可以使用 required 关键字来请求命名参数,例如:{required String name} (4认同)
  • 喜欢一个函数的多个命名参数,这很难找到!在文档的构造函数部分看起来会更好吗?;) (2认同)
  • 根据 https://www.dartlang.org/guides/language/language-tour#optical-positional-parameters,现在应该使用 `=` 而不是 `:` 指定默认值。 (2认同)

Sar*_*aja 11

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

  • 必填参数
  • 可选参数(位置,名称和默认值)

>>必填参数

必需参数是我们都熟悉的众所周知的旧样式参数

例如

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

findVolume(10,20,30);
Run Code Online (Sandbox Code Playgroud)

输出:

length = 10, breath = 20, height = 30
Run Code Online (Sandbox Code Playgroud)

>>可选位置参数

参数将用方括号[]公开,方括号参数是可选的。

例:

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

findVolume(10,20,30);//valid
findVolume(10,20);//also valid
Run Code Online (Sandbox Code Playgroud)

输出:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = null // no value passed so height is null
Run Code Online (Sandbox Code Playgroud)

>>可选的命名参数

  • 参数将用大括号{}公开
  • 大括号括起来的参数是可选的。
  • 必须使用参数名称来分配一个用colan分隔的值
  • 以大括号括起来的参数顺序无关紧要
  • 这些类型参数有助于我们避免在传递具有多个参数的函数的值时造成混淆。

例:

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
Run Code Online (Sandbox Code Playgroud)

输出:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = null
Run Code Online (Sandbox Code Playgroud)

>>可选的默认参数

  • 与可选的命名参数相同,此外,我们可以为此参数分配默认值。
  • 这意味着没有值传递,将采用默认值。

例:

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 
Run Code Online (Sandbox Code Playgroud)

输出:

length = 10, breath = 20, height = 30
length = 10, breath = 20, height = 10 // default value 10 is taken
Run Code Online (Sandbox Code Playgroud)

感谢您从此视频链接中获得清晰的解释,感谢视频创作者。

视频链接:OptionalPositionalParameters

视频链接:OptionalNamedParameters

视频链接:OptionalDefaultParameters


Ben*_*rth 9

来自 Flutter 的示例

命名参数

Duration构造函数采用命名参数:

const Duration(
{int days = 0,
int hours = 0,
int minutes = 0,
int seconds = 0,
int milliseconds = 0,
int microseconds = 0}
)
Run Code Online (Sandbox Code Playgroud)

位置参数

该类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]
)
Run Code Online (Sandbox Code Playgroud)

什么时候用哪个?

对于日期/时间,如果不指定月份,则指定日期是没有意义的。如果我告诉你星期一,你就不会知道我说的是哪个星期一。如果指定月份但不指定年份,则没有意义。枣子自然是由粗到细。当然,实际上您会假设下周一是哪个星期一,但程序不能这样假设。

对于Duration,您指定哪个并不重要。持续时间可以是 1 秒、1 毫秒或 5 天。如果我告诉你等 5 秒,我不需要告诉你0 天 0 小时 0 分钟 5 秒


Zoh*_*ule 7

位置参数:

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

void add(int x, [int y = 3]);
Run Code Online (Sandbox Code Playgroud)

这里 y 的默认值为 3

命名参数:

这些是可以通过传递参数名称后跟传递值以任何顺序传递的参数。例如:

void sum({int num1, int num2});
Run Code Online (Sandbox Code Playgroud)

这个函数是这样调用的:

sum(num1: 12, num2: 24);
Run Code Online (Sandbox Code Playgroud)

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


CoX*_*ier 6

文档中我们得知positionalnamed参数都是可选的,这意味着它们都可以不存在。

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

String say({String from, String msg})
Run Code Online (Sandbox Code Playgroud)

以上frommsgnamed参数,调用方法时say必须使用say(from: "xx", msg: "xx"). 钥匙不能缺席。

但是,如果您使用位置参数,那么您就自由了。


Bal*_*pur 5

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

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

void main() {
  sayHello('Govind');
}
Run Code Online (Sandbox Code Playgroud)