一、Dart泛型概述
在 Dart 語言中,泛型是指一個類或方法可以接受不同類型的參數。泛型可以幫助我們更好地封裝代碼,提高代碼的可重用性和安全性。
泛型的基本語法如下:
class ClassName<T> {
T method(T arg) {
return arg;
}
}
其中,<T> 表示泛型類型參數,可以是任何合法的 Dart 標識符。在上面的例子中,我們定義了一個泛型類 ClassName,它有一個泛型方法 method,該方法接受一個泛型參數 arg,並返回該參數。
二、Dart泛型擦除
Dart 通過泛型擦除來實現泛型。泛型擦除是指編譯器在編譯時會將泛型的具體類型替換為 Object 類型,並在必要時進行強制轉換。這就意味着,在運行時無法判斷泛型的類型。
示例代碼如下:
void main() {
List<int> list = [1, 2, 3];
print(list.runtimeType); // 輸出:List<int>
processList(list);
}
void processList(List<Object> list) {
print(list.runtimeType); // 輸出:List<int>
}
在上面的代碼中,我們先定義了一個 List<int> 類型的 list,然後將它作為參數傳遞給了 processList 方法。在 processList 方法中,我們將參數類型定義為 List<Object>,並輸出該參數的類型。我們會發現,輸出結果為 List<int>,而不是 List<Object>。這是因為在編譯時,泛型類型 int 被擦除,list 的實際類型變為 List<Object>。
三、Dart泛型序列化
Dart 通過序列化和反序列化來實現泛型。序列化是指將對象轉換為二進制格式或其他格式,以便於存儲或傳輸。反序列化是指將二進制格式或其他格式轉換為對象。
在 Dart 中,我們可以使用 json 庫來實現泛型序列化。示例代碼如下:
import 'dart:convert';
class Person<T> {
T name;
int age;
Map toJson() {
return {'name': name, 'age': age};
}
static Person fromJson(Map json, T Function(dynamic) fromJsonT) {
return Person<T>()
..name = fromJsonT(json['name'])
..age = json['age'];
}
}
void main() {
var person = Person<String>()
..name = '張三'
..age = 18;
var json = jsonEncode(person.toJson());
print(json); // 輸出:{"name":"張三","age":18}
var decodedJson = jsonDecode(json);
var decodedPerson = Person.fromJson(decodedJson, (dynamic name) => name.toString());
print(decodedPerson.name); // 輸出:張三
}
在上面的代碼中,我們先定義了一個泛型類 Person,通過 toJson 方法將 Person 實例轉換為 Map 對象。然後我們將 Map 對象編碼為 JSON 字符串,並輸出編碼結果。接着,我們將 JSON 字符串解碼為 Map 對象,並使用 fromJson 方法將 Map 對象轉換為 Person 對象。
四、Dart泛型類型限制
Dart 中可以使用 extends 關鍵字來限制泛型的類型。示例代碼如下:
abstract class Animal {
String getName();
}
class Cat implements Animal {
String name;
Cat(this.name);
String getName() => name;
}
class Dog implements Animal {
String name;
Dog(this.name);
String getName() => name;
}
class AnimalList<T extends Animal> {
final List<T> _animals = [];
void add(T animal) {
_animals.add(animal);
}
void printNames() {
for (var animal in _animals) {
print(animal.getName());
}
}
}
void main() {
var animalList = AnimalList<Animal>();
animalList.add(Cat('小花'));
animalList.add(Dog('旺財'));
animalList.printNames(); // 輸出:小花 旺財
}
在上面的代碼中,我們先定義了一個抽象類 Animal,然後定義了兩個實現類 Cat 和 Dog,它們都繼承自 Animal。接着,我們定義了一個泛型類 AnimalList,它用於存儲 Animal 類型的對象。在 AnimalList 的泛型類型參數 T 上使用 extends 關鍵字,表示 T 只能是 Animal 或 Animal 的子類。在 AnimalList 類中,我們添加了 add 和 printNames 方法,add 方法用於向 _animals 列表中添加 Animal 類型的對象,printNames 方法用於輸出 _animals 中所有對象的名稱。
五、Dart泛型類型推斷
在 Dart 2.0 中,編譯器可以根據變量的類型自動推斷泛型類型參數。示例代碼如下:
void main() {
var list = <int>[1, 2, 3];
var index = 2;
var item = list[index];
print(item); // 輸出:3
var map = <String, int>{
'one': 1,
'two': 2,
'three': 3
};
var key = 'two';
var value = map[key];
print(value); // 輸出:2
}
在上面的代碼中,我們先定義了一個類型為 List<int> 的 list,然後定義了一個變量 index,它的值為 2。接着,我們根據 index 取出了 list 中的第三個元素,並將結果賦值給變量 item。由於 list 的類型已經被推斷為 List<int>,所以編譯器可以自動推斷出 item 的類型為 int。同理,我們定義了一個類型為 Map<String, int> 的 map,然後根據 key 取出了 map 中的一個值,並將結果賦值給變量 value,編譯器可以自動推斷出 value 的類型為 int。
原創文章,作者:PHZJZ,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/324409.html