iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
1
Software Development

Dart 語言 - 開啟 Flutter 的鑰匙系列 第 9

Day9:匿名函數(Anonymous function)

  • 分享至 

  • xImage
  •  

上一篇文章介紹了函數,本篇繼續介紹進階的函數用法。

在 Dart 裡,全部的項目都是 Object ,當然這也包括函數;這代表什麼意思呢?

  1. 可以將函數作為參數傳入其他的函數內。
  2. 可以將函數指派給變數。
  3. 可以作為函數的回傳值。
  • 先來看一個 ListforEach
void printIt(String element){
	print(element);
}
var names = ['Alex', 'Johnson', 'Lex'];

list.forEach(printIt);

為什麼 list.forEach 可以接收 printIt 呢?

我們來看一下 forEach 的原始碼:

void forEach(void f(E element)) {
    for (E element in this) f(element);
}

forEach 含有一個引數,而這個引數是 void f(E element),是不是有點眼熟呢?

這是一個函數的定義,函數名稱為 f ,回傳值為 void,傳入的參數為 E element,這邊的E表示是泛型,意思是任何型態都可以接受。(我將在後面介紹泛型)。

接者看看 forEach 的實作

for (E element in this) f(element);

這是一個迭代的 for 迴圈,其中 this 代表呼叫 forEachlist,該迴圈會將 list 裡的每一個元素走訪一次,接者呼叫傳入 forEach 的引數,並將該元素傳給傳入的引數。

所以,當我們傳入一個 void printIt(String element)list 裡面的每一個元素都被丟進 printIt,並且執行它。

那麼,如果要呼叫 forEach 函數,是不是一定要先定義一個函數,並將該函數傳給 forEach 呢?

→ 不用,我們可以使用匿名函數。

匿名函數 (Anonymous function)

將上方的範例改為用匿名函數:

var names = ['Alex', 'Johnson', 'Lex'];

list.forEach((element){
	print(element);
});

發現什麼?

若一個函數可以接受函數作為引數,那麼我們不一定需要將需傳入的函數定義出來。我們可以直接在呼叫函數的地方直接實作它。

有時候,有些函數只有提供給物件使用,定義一個函數卻無法複用,此時就很適合使用匿名函數。

匿名函數如同一般的函數一樣,我們也可以使用表達式 (Expression) 表示。

將上方範例改為用表達式:

list.forEach((element) => print(element)); 

是不是簡單多了呢?

函數除了可以由函數作為引數,還可以當作回傳值

下面的範例:

Function timesX(int multiplicand){
	return (int i) => i * multiplicand;
}

var time3 = timesX(3);
var time5 = timesX(5);

print(time3(2)); //6
print(time5(3)); //15
  • timesX(int multiplicand):將 multiplicand 傳入函數 timesX 中,並與函數內的 i 相乘得到結果。
  • 可以看出 return 值是一個匿名函數。

有沒有注意到,為什麼 timesX(3) 中的 3 不會與 timesX(5) 互相影響 (兩個參數都傳給了 timesX 的 multiplicand)。

→ 這稱為語彙封包 (Lexical Closures):timesX(int multiplicand) 中的參數因為被包在大括弧裡面,所以其作用域只有在括弧括起來的範圍。即使使用相同的函數名稱宣告變數,還是算是不同的語彙封包。

小結

由於 Dart 的 函數 (Function) 是物件 (Object),所以我們可以將函數當作變數,作為函數的參數,甚至當作函數的回傳值。

作為函數的參數,我們可以使用匿名函數,省去不必要的函數宣告。

作為回傳值,我們可以將不同的變數帶入,創造出相似卻又不同的函數,因為所有帶入的參數都會因為語彙封包而互不影響。


上一篇
Day8:函數 (Functions)
下一篇
Day10:運算子(上) - Operators
系列文
Dart 語言 - 開啟 Flutter 的鑰匙30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言