iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 22
1
Software Development

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

Dart 22:將函數定義成型別吧。 (Typedef)

  • 分享至 

  • xImage
  •  

在 Dart 中,所有的項目都是物件 (Object),包括函數 (Functions) 也是物件。我們可以將函數作為另一個函數的回傳值,也可以作為函數的參數。關鍵字 typedef 定義一個名稱供函數回傳以及宣告使用。 typedef 也可稱為函數別名 (Function-alias)。

語法

typedef name(parameters)

範例

typedef Calculator(int x, int y);
  • 這樣就定義好一個函數的別名 Calculator ,參數為 (int x, int y)

怎麼使用呢?

  • 有兩個函數,分別是 add(int x, int y) 以及 subtraction(int x, int y)
int add(int x, int y){
	return x + y;
}

int subtraction(int x, int y){
	return x - y;
}
  • 我們可以將這兩個函數指定到 typedef 定義好的函數別名上。
void main(){
	Calculator calculator;
	calculator = add;
	var result1 = calculator(2,1);
	
	calculator = subtraction;
	var result2 = calculator(4, 2);

	print(result1);
	print(result2);
}
//3
//2

發現什麼?

將函數作為物件可以直接指派給某變數,而這個變數的類型就是一個函數帶有兩個輸入參數,只要符合定義,就可以指派,跟基本類型的用法一樣。

如果有另一個函數,他的輸入參數數量不一樣,就沒有辦法指定給 Calculator

int add3(int x, int y, int z){
	return x + y + z;
}

void main(){
	Calculator calculator;
	calculator = add3; //Compilation-error
}

有一個函數 isEquals() ,用來比對兩個數值是否相同,這個函數的回傳值是 bool ,跟前面的例子回傳的 int 不同。

bool isEquals(int x, int y){
	return x == y;
}

我們同樣可以將這個函數指定給 Calculator calculator 上。

void main(){
	Calculator calculator;
	calculator = isEquals;
	calculator(1, 1); //true
}

發現什麼?

預設 typedef 定義的函數回傳值是 dynamic ,也就是說,任何的物件都可以被回傳。包括 void

那麼,我們要如何定義 typedef 的回傳值呢?

更新一下語法:

typedef return_type function_name(parameters);

將上面的範例改為

typedef int Calculator(int x, int y);
void main(){
	Calculator calculator;
	calculator = isEquals; //Compilation-Error
}

typedef 可以將函數注入至類別當中

範例:

typedef MyFunction = int Function(int, int);

class MyClass{
	MyFunction function;
	MyClass(this.function);

	int call(int x, int y){
		return function(x, y);
	}
}
  • 使用方式 (搭配 Callable class使用)
void main(){
	var myClass = MyClass(add);
	myClass(10, 20); //30
}

int add(int x, int y){
	return x + y;
}

Effective Dart 中,有幾條建議與 typedef 相關。

AVOID defining a one-member abstract class when a simple function will do.
避免定義只包含一個簡單的函數的抽象類別。

abstract class Predicate<E> {
  bool test(E element);
}

改成

typedef Predicate<E> = bool Function(E element);

DON’T use the legacy typedef syntax.
不要使用舊的 typedef 語法

//舊
typedef void F();
//新
typedef F = void Function();

小記

在 Dart 中,所有的項目都是物件,就連函數也不例外, typedef 可以把函數定義成型別,接者就可以當作基本型別的方式來使用。

既然可以當作基本型別使用,那麼當作函數的參數,類別的屬性,都是允許的。


上一篇
Day 21:像呼叫函式一樣的呼叫類別吧。(Callable class)
下一篇
Dart23:異步處理
系列文
Dart 語言 - 開啟 Flutter 的鑰匙30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言