iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Mobile Development

從零開始以Flutter打造跨平台聊天APP系列 第 4

Day-4 Dart 簡介(3):Function

  • 分享至 

  • xImage
  •  

Generated from Stable Diffusion 3 Medium

經過前兩回的 Dart 教學,相信大家已經掌握 Dart 變數、流程控制和一些常用的容器,這次的教學會著重在函式 Function 的部分,在 Dart 中,函式的寫法比較多種,除了像一般 C, Java, Javascript, Go 等語言基礎的寫法,也支援更彈性的操作,比如可命名參數的 Fucntion,或者可選位置參數的 Fucntion。

這種作法可以實現 C++, Java 中的 overload。傳統的 overload 雖然學習上方便,但可能會讓程式碼變得很複雜,而且在調用時也必需再三確認文件。Dart 的作法與 Python 類似,在 Python 中,Function 可以使用預設參數或不定參數來模擬 overload 的行為。

在 Flutter 中,由於有很多參數可以進行調整,因此經常使用可命名參數的 Function。掌握 Dart 中特有的 Function 寫法對於後續 Flutter 的學習相當重要!

範例程式碼:https://github.com/ksw2000/ironman-2024

Function

官方教學文件:https://dart.dev.org.tw/language/functions

在 Dart 中,函式的使用和 Java 的寫法類似,但是又多了更多的功能,以下是一個試範:

int add(int a, int b) {
  return a + b;
}

void main() {
  print(add(3, 4));
}

其中,函式 add 的輸出為 int,而輸入 a, b 也都為 int。而 main() 則是 dart 預設執行的函式。跟 C, Java, Go, Typescript 一樣,對於那些沒有回傳值的函式我們可以使用 void 來表示。

另外,我們也可以利用 => 簡化函式的寫法

int add2(int a, int b) => a + b;

函式本身也屬於一個 Function 型別,所以我們可以將 Function 當做參數傳入 function。

void add3(int a, int b, Function callback) {
  callback(a + b);
}

void main(){
  add3(4, 5, (n) {
    print(n);
  });
  
  // 編譯成功,但執行時會報錯
  // add3(6, 7, (m, n)){
  //   print("$m $n");
  // }
  // Unhandled exception:
  // NoSuchMethodError: Closure call with mismatched arguments: function 'main.<anonymous closure>'
}

直接以 Function 來傳送可能會有一個問題,那就是使用者不知道該設計怎樣的 function,比如上述的例子中,callback 的型態其實應該是 void callback(int),也因此我們可以換成以下的寫法:

void add4(int a, int b, void Function(int) callback) {
  callback(a + b);
}

void main(){
  add4(6, 7, (e) {
    print(e);
  });
}

可命名參數的 Fucntion

在 Flutter 中,有些時候因為函式的功能很強大,所以會有非常多參數可以調整,但是要調整時,我們會記不住他的位置,而且有些參數會有預設值,不需要使用者自己設定,此使我們可以使用「可命名參數」,這類參數會要求使用者在調用函式時寫上參數的名字,而不是靠位置決定。

int add5({int? a, int? b}) {
  int aa = a ?? 0;
  int bb = b ?? 0;
  return aa + bb;
}

void main(){
  print(add5(a: 2)); // 2
  print(add5(b: 3)); // 3
  print(add5(a: 2, b: 3)); // 5
}

由於使用者可以不填入 a 或不填入 b,因此在接收函式時,要使用 int? 而不是 int。當使用者沒有決定其中一個參數時,預設就是傳送 null。此時你可能會有疑問,我們不能自己更改預設值嗎?其實是可以的

int add6({int a = 0, int b = 0}) {
  return a + b;
}

另外,我們也可以要求使用者一定要填寫某個參數。只要在參數前加上 required 即可,這樣使用這就一定得輸入該參數。比如我們可以要求使用者一定要使用參數 a。早期的 Dart 1.x 似乎沒有這個功能,這個功能原本是 Flutter 利用裝飾器實作的,當時會使用 @required 來表示該參數必選,後來才逆輸入給 Dart 的編譯器。

int add7({required int a, int b = 0}) {
  return a + b;
}

void main(){
  add7(a: 3); // 3
  add7(b: 3); // 編譯不過
}

可選位置參數的 Fucntion

有時候,我們只有最後幾個參數供使用者選擇,此時我們可以利用中括號 [],將這些可有可無的參數提供給使用者。

int add8(int a, [int? b, int? c]) {
  return a + (b ?? 0) + (c ?? 0);
}

void main(){
  print(add8(2)); // 2
  print(add8(2, 3)); // 5
  print(add8(2, 3, 4)); // 9
}

跟上一節的寫法類似,我們仍然可以提供預設值給那些參數

int add9(int a, [int b = 0, int c = 0]) {
  return a + b + c;
}

後記:原本今天想講一些 class,但感覺留在明天講比較段落分明?


上一篇
Day-3 Dart 簡介(2):List, Map 及 Null Safety
下一篇
Day-5 Dart 簡介(4):Class, Abstract Class
系列文
從零開始以Flutter打造跨平台聊天APP30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言