[英]What is the difference between named and positional parameters in Dart?
Dart 同時支持命名可選參數和位置可選參數。 兩者之間有什么區別?
另外,您如何判斷是否實際指定了可選參數?
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!
}
據我了解,在 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
>> 可選命名參數
例子:
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
感謝此視頻鏈接給出的清晰解釋,感謝視頻創作者。
位置參數:
它們與默認參數相同。 例如:
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');
}
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})
上面from
和msg
是named
參數,當你調用方法say
時,你必須使用say(from: "xx", msg: "xx")
。 鑰匙不能缺席。
然而,如果你使用位置參數,你是自由的。
Dart 有兩種函數參數: positional
和named
。
可選位置參數
位置參數是您可能熟悉的類型:
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.