認識 Dart function 的參數: positional parameters、optional positional parameters、named parameters、required named parameters
定義 Dart function 時,我們可以宣告四種類型的參數,positional parameters、optional positional parameters、named parameters、required named parameters,以下我們逐一介紹它們的語法、特性和差異。
- positional parameters (必填的位置參數)。
- 使用 [ ] 宣告 optional positional parameters(可省略的位置參數)。
- 使用 { } 宣告 named parameters(可省略的命名參數)。
- 使用 required 宣告 named parameters。(必填的命名參數)
- 混搭 positional parameters、optional positional parameters 和 named parameters。
- 比較表。
ps: 可從 DartPad 練習以下的程式範例。
positional parameters (必填的位置參數)
positional parameters 是最基本的參數寫法,直接在 function 的 ( ) 裡宣告參數的型別和名字,就像 function add 的 number1 和 number2。
void main() {
var sum = add(10, 20);
print(sum);
}
int add(int number1, int number2) {
return number1 + number2;
}
結果
30
傳入 positional parameters 的內容時,有以下幾點要注意的地方。
- 要照順序傳入。
以 add(10, 20)
為例,10 對應 number1,20 對應 number2。
- positional parameters 不可省略。
void main() {
var sum = add(10);
print(sum);
}
int add(int number1, int number2) {
return number1 + number2;
}
add(10)
只傳入 1 個參數,應該要傳入 2 個,錯誤訊息如下。
Error: Too few positional arguments: 2 required, 1 given.
var sum = add(10);
使用 [ ] 宣告 optional positional parameters(可省略的位置參數)
如果希望剛剛照順序傳入的參數可省略,我們可宣告 optional positional parameters。
只要將參數包在 [ ] 裡,即可讓它變成 optional positional parameters。既然參數可省略,表示參數應該要有預設值或型別為 nullable,如此省略時 Dart 才能知道參數的內容。
以下我們分別說明有預設值或型別為 nullable 的寫法。
- 有預設值的 optional positional parameters。
number1 = 1
將 number1 預設為 1,number2 = 2
將 number2 預設為 2。
void main() {
var sum = add(10, 20);
print('add(10, 20) = $sum');
sum = add();
print('add() = $sum');
sum = add(10);
print('add(10) = $sum');
}
int add([int number1 = 1, int number2 = 2]) {
return number1 + number2;
}
結果。
add(10, 20) = 30
add() = 3
add(10) = 12
add(10) 的結果為 12,因為參數要照順序傳入,因此 10 對應 number1,number2 採用預設值 2。
值得注意的,當 positional parameters 沒有加 [ ],呼叫 function 時一定要傳入參數的內容,因此它設定預設值完全無意義。
int add(int number1 = 1, int number2 = 2) {
return number1 + number2;
}
以上程式將產生錯誤。
Error: Non-optional parameters can't have a default value.
int add(int number1 = 1, int number2 = 2) {
- 型別為 nullable 的 optional positional parameters。
void main() {
var sum = add(10, 20);
print('add(10, 20) = $sum');
sum = add(10);
print('add(10) = $sum');
sum = add();
print('add() = $sum');
}
int add([int? number1, int? number2]) {
if (number1 != null && number2 != null) {
return number1 + number2;
} else if (number1 != null) {
return number1;
} else {
return 0;
}
}
結果。
因為參數要照順序傳入,所以如果只有傳一個數字時,它一定是 number1,不會是 number2。
add(10, 20) = 30
add(10) = 10
add() = 0
使用 { } 宣告 named parameters(可省略的命名參數)
我們可用 { } 定義 named parameter,它將帶來以下幾個好處。
- 傳入 named parameter 的內容時必須寫出參數的名字,它將讓程式的可讀性更好,一眼看出參數的意思。
- 可用任意的順序傳入 named parameter,不用再怕順序寫錯。
- name parameter 可省略。既然參數可省略,表示參數應該要有預設值或型別為 nullable,如此省略時 Dart 才能知道參數的內容。
以下我們改寫剛剛的例子說明。
- 有預設值的 named parameters。
void main() {
var sum = add(number1: 10, number2: 20);
print('add(number1: 10, number2: 20) = $sum');
sum = add(number2: 20, number1: 10);
print('add(number2: 20, number1: 10) = $sum');
sum = add(number1: 10);
print('add(number1: 10) = $sum');
sum = add(number2: 20);
print('add(number2: 20) = $sum');
sum = add();
print('add() = $sum');
}
int add({int number1 = 1, int number2 = 2}) {
return number1 + number2;
}
結果。
add(number1: 10, number2: 20) = 30
add(number2: 20, number1: 10) = 30
add(number1: 10) = 12
add(number2: 20) = 21
add() = 3
說明。
- 傳入 named parameter 的內容時必須寫出參數的名字。
格式為參數名字,冒號和內容,因此 add(number1: 10, number2: 20)
表示 number1 的內容為 10,number2 的內容為 20。
沒有寫參數名字將出現錯誤,比方以下程式將讓 Dart 誤會,它會認為 10 和 20 是 positional arguments。
var sum = add(10, 20);
2. 可用任意的順序傳入 named parameter。
由於有名字,我們用任意的順序傳入參數,不用再怕順序寫錯,add(number2: 20, number1: 10)
也是可以的。
- 型別為 nullable 的 named parameters。
void main() {
var sum = add(number1: 10, number2: 20);
print('add(number1: 10, number2: 20) = $sum');
sum = add(number2: 20, number1: 10);
print('add(number2: 20, number1: 10) = $sum');
sum = add(number1: 10);
print('add(number1: 10) = $sum');
sum = add(number2: 20);
print('add(number2: 20) = $sum');
sum = add();
print('add() = $sum');
}
int add({int? number1, int? number2}) {
if (number1 != null && number2 != null) {
return number1 + number2;
} else if (number1 != null) {
return number1;
} else if (number2 != null) {
return number2;
} else {
return 0;
}
}
結果。
add(number1: 10, number2: 20) = 30
add(number2: 20, number1: 10) = 30
add(number1: 10) = 10
add(number2: 20) = 20
add() = 0
使用 required 宣告 named parameters(必填的命名參數)
如果想要 name parameter 不可省略,則可在參數前加上 required。由於參數不可省略,因此我們也不能設定預設值。不過型別設為 nullable 倒是可以,因為呼叫時可傳入 null。
void main() {
var sum = add(number1: 10, number2: 20);
print('add(number1: 10, number2: 20) = $sum');
sum = add(number2: 20, number1: 10);
print('add(number2: 20, number1: 10) = $sum');
}
int add({required int number1, required int number2}) {
return number1 + number2;
}
結果。
add(number1: 10, number2: 20) = 30
add(number2: 20, number1: 10) = 30
number1 和 number2 加了 required,因此呼叫 add 時一定要傳入 number1 和 number2 的內容。
以下程式少傳了 number2,因此會出現錯誤。
var sum = add(number1: 10);
錯誤訊息如下。
Error: Required named parameter 'number2' must be provided.
var sum = add(number1: 10);
值得注意的,required 會讓 named parameters 成為必填的參數,因此定義 function 時設定參數的預設值不再有意義。
int add({required int number1 = 1, required int number2}) {
return number1 + number2;
}
以上寫法將出現錯誤訊息。
Error: Named parameter 'number1' is required and can't have a default value.
int add({required int number1 = 1, required int number2}) {
混搭 positional parameters、optional positional parameters 和 named parameters
定義 function 時我們也可混搭多種類型的參數,不過不能同時包含 optional positional parameters 和 named parameters,因此混搭只有以下兩種可能。
- positional parameters 和 optional positional parameters。
- positional parameters 和 named parameters。
為了讓 Dart 正確判斷傳入的參數,function 定義時 positional parameters 要寫在前面,optional positional parameters 或 named parameters 要寫在後面。
以下我們分別舉例說明。
- positional parameters 和 optional positional parameters。
void main() {
var sum = add(10, 20);
print('add(10, 20) = $sum');
sum = add(10);
print('add(10) = $sum');
}
int add(int number1, [int number2 = 2]) {
return number1 + number2;
}
結果。
add(10, 20) = 30
add(10) = 12
以 add(10)
為例,因為 positional parameter number1 寫在前面,Dart 才知道 10 是 number1,省略的是 number2。
若是順序顛倒將出現錯誤,比方以下程式將 optional positional parameters 寫在前面,positional parameters 寫在後面。
int add([int number1 = 1], int number2) {
return number1 + number2;
}
- positional parameters 和 named parameters。
呼叫時 named parameters 可照任意順序傳入,因此 add(10, number2: 20)
和 add(number2: 20, 10)
都是 ok 的。
void main() {
var sum = add(10, number2: 20);
print('add(10, number2: 20) = $sum');
sum = add(number2: 20, 10);
print('add(number2: 20, 10) = $sum');
sum = add(10);
print('add(10) = $sum');
}
int add(int number1, {int number2 = 2}) {
return number1 + number2;
}
結果。
add(10, number2: 20) = 30
add(number2: 20, 10) = 30
add(10) = 12