簡體   English   中英

Dart 中的命名參數和位置參數有什么區別?

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

Dart 同時支持命名可選參數和位置可選參數。 兩者之間有什么區別?

另外,您如何判斷是否實際指定了可選參數?

Dart 有兩種類型的可選參數: namedpositional 在討論差異之前,讓我先討論相似之處。

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!
}

據我了解,在 Dart 中,方法參數可以有兩種類型。

  • 必需參數
  • 可選參數(位置、命名和默認)

>> 必填參數

必需參數是我們都熟悉的眾所周知的舊式參數

示例

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

findVolume(10,20,30);

輸出:

length = 10, breath = 20, height = 30

>> 可選位置參數

參數將用方括號[ ]公開,方括號中的參數是可選的。

例子:

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

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

輸出:

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

>> 可選命名參數

  • 參數將用大括號 { } 公開
  • 花括號中的參數是可選的。
  • 必須使用參數名稱來分配一個用 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

輸出:

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

>> 可選默認參數

  • 與可選命名參數相同,此外我們可以為此參數分配默認值。
  • 這意味着沒有傳遞任何值,將采用此默認值。

例子:

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 

輸出:

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

感謝此視頻鏈接給出的清晰解釋,感謝視頻創作者。

視頻鏈接:OptionalPositionalParameters

視頻鏈接:OptionalNamedParameters

視頻鏈接:可選默認參數

位置參數:

它們與默認參數相同。 例如:

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

這里 y 的默認值為 3

命名參數:

這些參數可以按任何順序傳遞,方法是傳遞參數名稱,后跟傳遞的值。 例如:

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

這個函數是這樣調用的:

sum(num1: 12, num2: 24);

命名參數也可以有默認值。

當使用“paramName : value”語法指定函數的參數時,它就是命名參數。 通過將這些參數括在 [ 和 ] 括號之間,可以將它們呈現為可選的。 可以在以下 Hello World 程序中演示此功能的基本演示:

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

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

來自 Flutter 的示例

命名參數

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

什么時候用哪個?

對於dates/times ,如果您不指定月份,則指定一天是沒有意義的。 如果我在星期一告訴你,你不會知道我說的是哪個星期一。 如果您指定月份但不指定年份,則沒有意義。 日期自然從粗到細。 當然,實際上你會假設下周一是哪個星期一,但程序不能這樣假設。

對於Duration ,您指定哪個都沒有關系。 A Duration of time 可以是 1 秒、1 毫秒或 5 天。 如果我告訴你等待 5 秒,我不需要告訴你0 天 0 小時 0 分鍾 5 秒

doc我們得到positional參數和named參數都是可選的,這意味着它們都可以不存在。

在我看來, named參數比positional參數更嚴格。 例如,如果您聲明這樣一個方法:

String say({String from, String msg})

上面frommsgnamed參數,當你調用方法say時,你必須使用say(from: "xx", msg: "xx") 鑰匙不能缺席。

然而,如果你使用位置參數,你是自由的。

Dart 有兩種函數參數: positionalnamed

可選位置參數

位置參數是您可能熟悉的類型:

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

使用 Dart,您可以通過將這些位置參數括在括號中來使它們成為可選的:

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

可選的位置參數總是在函數參數列表的最后。 除非您提供另一個默認值,否則它們的默認值為 null:

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

實現一個名為joinWithCommas()的函數,該函數接受一到五個整數,然后返回由逗號分隔的這些數字組成的字符串。 以下是函數調用和返回值的一些示例:

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

函數調用

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

返回值

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

可選的命名參數

使用花括號語法,您可以定義具有名稱的可選參數。

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

如您所料,這些參數的值默認為 null,但您可以提供默認值:

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

一個函數不能同時具有可選的位置參數和可選的命名參數。

代碼示例

copyWith()實例方法添加到 MyDataObject 類。 它應該采用三個命名參數:

int newInt
String newString
double newDouble

調用時, copyWith()應根據當前實例返回一個新的MyDataObject ,並將來自前面參數(如果有)的數據復制到對象的屬性中。 例如,如果newInt為非空,則將其值復制到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:
}

在下面的方法中:

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

體重和身高是位置參數,年齡是命名參數。

我們將調用如下方法:

getBMI(65, 175, age: 35);

如您所見,托管參數使調用站點更容易理解。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM