发布于 

【Dart】泛型梳理

Dart泛型

泛型主要解决的是接口方法复用性、以及对不特定数据类型的支持(类型校验)

泛型方法

泛型方法最主要的就是不指定类型方法的参数类型或者是返回类型,也就是放弃类型检查,想实现的是传入什么,返回什么。

比如:传入number类型必须返回number类型,传入String类型必须返回String类型。

定义一个泛型方法:

1
2
3
T getValue<T>(T value) {
return value;
}

调用:

1
2
3
print(getValue<String>("Dart 泛型方法"));

print(getValue<int>(123));

泛型类

泛型类型用于类的定义中,故被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口,如:List、Set、Map。

1
2
3
4
5
6
7
8
9
10
11
12
class MyList<T> {

List list = <T>[];

void add(T value) {
this.list.add(value);
}

List getList() {
return list;
}
}

上述代码中通过泛型T来标识任意类型,可以在实例化的时候传入所需的类型,但是它们却有相同的实现方法。

泛型接口

在Java中使用泛型接口格式是:

1
interface 接口名<类型参数表>

在前面的文章有说到Dart的接口没有interface关键字定义接口,所以Dart中使用泛型接口的一般格式是:

1
abstract class 接口名<类型参数表>

定义一个泛型接口:

1
2
3
4
5
6
abstract class Cache<T> {

getByKey(String key);

void setByKey(String key, T value);
}

那的实现类就是实现这个接口:

1
2
3
4
5
6
7
8
9
10
11
12
class MemoryCache<T> implements Cache<T>{

@override
getByKey(String key) {
return null;
}

@override
void setByKey(String key, T value) {
print("value=${value} 已存储");
}
}

调用:

1
2
3
var mc = MemoryCache<Map>();

mc.setByKey('index', {"name": "Mike", "age": 22});

Dart中的库

库的作用很明显可以让的开发模块化,在Dart中,库的使用时通过import关键字引入的。

Dart中的库主要有三种:

  • 自定义的库
    import 'lib/xxx.dart';

  • 系统内置库

    1
    2
    import 'dart:math';
    import 'dart:io';
  • Pub包管理系统中的库

1
2
3
4
5
pub.dev/packages

pub.flutter-io.cn/packages

pub.dartlang.org/flutter/

需要在自己想项目根目录新建一个pubspec.yaml;

在pubspec.yaml文件 然后配置名称 、描述、依赖等信息;

然后运行pub get获取包下载到本地;

项目中引入库import ‘package:http/http.dart’ as http。

Dart库引入冲突解决

当引入两个库中有相同名称标识符的时候,如果是Java通常通过写上完整的包名路径来指定使用的具体标识符,甚至不用import都可以,但是Dart里面是必须import的。当冲突的时候,可以使用as关键字来指定库的前缀,如下:

1
2
import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;

库的部分导入

先定义一个userInfo.dart,并声明一些方法

1
2
3
4
5
6
7
void getName() {
print('Mike');
}

void getAge() {
print(22);
}

这个时候如果只需要getName()这个方法属性就可以使用部分导入:

1
import 'userInfo.dart' hide getName;

这样就只可以调用getName()方法,无法使用getAge()。

延时加载库

延迟加载也就是为懒加载,它可以让在需要的时候再进行加载,懒加载的好处是优化App的启动。

懒加载的使用可以通过deferred as关键字来指定。

定义一个lazyLoad.dart:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void init(){
Person person = Person();
person.getName();
}

class Person{

void getName() {
print('Mike');
}
void getAge() {
print(22);
}
}

然后延迟加载:

1
import 'lazyLoad.dart' deferred as lazyload; // deferred as 关键字指定

这里用到了async和await关键字,展开说一下。

async和await

asyncawait两个关键字是配合一起使用的,只有async方法才能使用await关键字调用方法,如果调用别的async方法必须使用await关键字。

  • async是让方法变成异步;

  • await是等待异步方法执行完成。

声明一个异步反方法:

1
2
3
asyncSample() async {
return 'Dart async';
}

调用:

1
2
3
void main() async {
var result = await asyncSample();
}

这里看main方法也加了async关键字,这是因为方法里要是使用await关键字,上面定义说了只有async方法才能使用await关键字调用方法