0%

[Flutter讀書會]Dart101:Functions方法

前提情要

說說Dart程式語言,原本是來實作Angular前端框架而存在,早期Angular框架還有分兩派,TypescriptDart,但發展到後面,完全被Typescript取代。時間線移回現在,Dart程式語言從Flutter2017年中發佈開始,又重回戰場。筆者在看Function這個章節時,不禁讓筆者想到這些歷史背景,原本Dart程式語言是為了開發Web應用程式的阿,因此某些特性上跟Javascript特性相符也不是沒有道理的,例如: Lexical Scope語彙範疇。每個程式語言都要有的Function方法,Dart語言的世界裡Function方法會是甚麼樣子呢,趕緊跟著筆者的腳步來看看吧。

內容

筆者這邊還是簡單列一下筆者這邊的開發環境

  • 作業系統:Mac OS
  • Dart版本:2.17.6
  • 編輯器:Visual Studio Code

前提情要提到的背景,讓筆者繼續說下去吧,與JS一樣,Dart語言世界裡,處處皆為物件,Function也不例外,意即Function可以當作Variable變數,也可以當作參數傳到另一個Function

宣告方式

跟其他語言差不多,format

{回傳型別} {Function名稱}({參數型別} {參數名稱}){
//邏輯處理
}

1
2
3
4
5
6
7
8
9
10
// 標準寫法
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 也可以不指定資料型別(筆者建議不要使用)
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 也可以使用箭頭函式(若處理邏輯少則可以考慮使用)
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

參數

參數這節主要敘述的是參數宣告方式有以下幾種

  • 指定名稱參數宣告
1
2
3
4
/// Sets the [bold] and [hidden] flags ...
void enableFlags({bool? bold, bool? hidden}) {...}
// 呼叫方式(可以指定參數名稱:參數值)
enableFlags(bold: true, hidden: false);
  • 必填寫參數宣告
1
2
// required關鍵字指定該參數為必宣告,若呼叫時不宣告該參數則編譯器會爆錯
const Scrollbar({super.key, required Widget child});
  • 選擇性參考宣告
1
2
3
4
5
6
7
8
// 若參數為選擇性選填則使用大括弧[]括起來即可
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
return result;
}
  • 參數給預設值宣告
1
2
3
4
5
// 可以設定參數的預設值,直接使用=符號指定參數值即可
void enableFlags({bool bold = false, bool hidden = false}) {...}

// 因為上方Function宣告時有指定預設值,因此下方呼叫時沒有宣告hidden也是正確的
enableFlags(bold: true);
  • 選擇性參數給預設值宣告
1
2
3
4
5
6
7
String say(String from, String msg, [String device = 'carrier pigeon']) {
var result = '$from says $msg with a $device';
return result;
}

// 沒有給device變數的值,因此會帶預設值:carrier pigeon
assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');

Main Function

接著看到的是每個application的入口,main()這個function,主要特色為

  • 回傳值為void
  • 選擇性參數List<string>
  • 可透過第三方套件https://pub.dev/packages/args,解析command line中傳入的arguments參數

Function當傳入參數

這個真的是一大福音,筆者平常工作使用的C#程式語言,需要特別透過delegate類才能做到這種由外部決定實作,等於input, output相符即可,以官方文件中的例子來說

1
2
3
void printElement(int element) {
print(element);
}

以上述function來說,約法三章的內容是inputint資料型別,outputvoid,只要符合這種input, output的場合就派上用場

1
2
3
4
var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);

以上述程式碼來說,forEach中得到的就是int資料型別,且這個執行沒有回傳值,符合outputvoid,因此可以將printElement當作參數傳進去。

匿名函式

這就是滿好解釋的了,就像main(),或者上節提到的printElement()都算是有名字的函式,就以剛剛的printElement()函式來說,也可以直接寫成匿名(沒有名字)函式

1
2
3
4
const list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});

Lexical Scope語彙範疇

筆者覺得參考連結中的文章介紹的滿詳細的,這邊就不多著墨解釋,因為再解釋下去也沒有比參考連結中講的好,倒不如直接參考該連結即可

結論

參考