集合与泛型
除了变量与基本类型介绍的基本类型,Dart 标准库还提供了很多其他类型,比如最常用的集合类型(Collections)。
泛型(Generics)可以提高类型安全并减少重复代码,而集合类型几乎都支持泛型,所以本节也将对它进行简要介绍。
集合
Dart 的集合类型主要是来自 dart:core
库的 List
、Set
和 Map
。
List
List
表示有序的数据列表,它其实就是其他语言中常见的数组(array)。
List
可以使用字面量(如:[a1, a2]的形式
)或构造函数创建。
var gameList = ['Halo', 'God of War']; // 字面量形式
gameList = new List(); // 使用构造函数
gameList.add('The Witcher'); // 使用add方法添加数据
gameList.add('Dark Souls');
// 通过getter或索引访问元素
print(gameList.frist);
print(gameList.last);
print(gameList[0]);
// 通过for...in循环遍历
for (var game in gameList) {
print(game);
}
Set
Set
是无序的数据集合,其中对象不可(不会)重复。
Set
可以使用字面量(如:{'dart', 'javascript'}
)或构造函数创建。
注意:访问Set
中的元素时,它们的顺序不能得到保证,默认顺序为元素的添加顺序。
var gameSet = {'Halo', 'God of War'}; // 字面量形式
gameSet = new Set(); // 使用构造函数
gameSet.add('The Witcher'); // 使用add方法添加数据
gameSet.add('Dark Souls');
// 通过getter访问元素
print(gameSet.frist);
print(gameSet.last);
// 通过for...in循环遍历
for (var game in gameSet) {
print(game);
}
Map
Map
是无序的键值对集合,键(key)和值(value)可以是任意类型,其中键不可(不会)重复,值可以重复。
Map
可以使用字面量(如:{'first': 'dart', 'second': 'javascript'}
)或构造函数创建。
注意:在没有泛型参数的情况下,空Map
字面量和空Set
字面量的写法都是{}
。因为 Dart 的Set
字面量是后加入的,所以{}
将默认识别为Map
类型。
var gameMap = {'microsoft': 'Halo', 'sony' :'God of War'}; // 字面量形式
gameMap = new Map(); // 使用构造函数
gameMap['cdpr'] = 'The Witcher'; // 使用[]添加数据
gameMap['fromsoft'] = 'Dark Souls';
print(gameMap['fromsoft']); // 使用[]访问数据
// 通过for...in循环遍历值
for (var game in gameMap.values) {
print(game);
}
泛型
泛型(Generics)即泛化的类型,也就是参数化的类型。使用泛型可以提升编译输出代码的质量,同时可以减少重复代码。
Dart 标准库中的很多类型都支持泛型,而集合类型是其中的代表。
定义和使用
与其他很多支持泛型的语言一样(如:Java,C#),Dart 泛型的定义和使用,都是在类型名称后添加 <类型参数1, 类型参数2, ...>
。
在定义泛型类时,类型参数通常使用E, T, S, K 和 V 等字母表示;而在泛型类被实例化时,类型参数需要填入实际的类型。
如果需要限定类型参数的范围,可以使用<T extends BaseType, ...>
的形式定义类型参数,即表示本类型只接受BaseType
类或其子类。
注意:如果泛型类是通过字面量形式创建,类型参数必须写在字面量前面
// 自定义泛型类
class Game {}
class GameLibrary<T extends Game> {
List<T> gameList;
}
// 使用泛型类
var gameList = new List<String>();
var scoreMap = <String, int>{}; // 字面量
// var gameLibrary = new GameLibrary<String>(); // 错误
var gameLibrary = new GameLibrary<Game>(); // ok
使用泛型的类将获得类型安全,在集合类型中的表现就是不能向其中添加除泛型参数之外的类型
var gameSet = new Set<String>(); // 字符串Set
gameSet.add('Dark Souls'); // OK
gameSet.add(123); // 添加数字,编译报错
注意:不添加类型参数的情况下,类型参数一般会被推断为dynamic
,表示不对类型进行限制
泛型方法
Dart 也支持泛型方法,