【Flutter 基础】 泛型

老孟Flutter

共 2237字,需浏览 5分钟

 · 2021-06-24

418556b67bdd3c5f5cd88c2d26e58802.webp

当我们查看 Flutter 源码的时候会发现源码中有大量的 代码,比如 List 的源代码

abstract class List<Eimplements EfficientLengthIterable<E{

<..> 标记表示泛型的概念,通常情况下,泛型使用单字母表示,比如:E,T,S,K和V。

为什么要使用泛型?它有什么作用?

在编译阶段进行类型安全检查

一个重要的作用是泛型会在编译阶段进行类型安全检查,比如有一个 String 类型集合:

List<String> list = [];

list 是一个String类型的集合,list 中的元素必须是String类型,添加其他类型时编译阶段报错

list.add(1); //编译不通过

假设不使用泛型,定一个集合:

List list1 = [];

list1 中可以添加任意类型的数据:

list1.add('value');
list1.add(1);

编译都可以通过,list1 等价于如下的定义:

List<dynamic> list1 = [];

减少重复代码

泛型可以有效的减少重复代码,一个典型使用场景:服务端返回的接口通常是统一的格式,比如返回如下json格式:

{
 "code"0,
 "msg""",
 "data": {}
}

每一个接口都会返回 codemsgdata 为业务数据,可以每一个接口返回的实体类型都进行如下定义:

class Data1{
  String code;
  String msg;
  dynamic data;
}

这是每一个实体类型都会包含codemsg字段,我们可以使用泛型去掉重复代码:

class DataBase<T>{
  String code;
  String msg;
  T data;
}

class Person {
  String name;
  Person(this.name);
}

使用:

var data = DataBase<Person>();

List Map Future Stream 使用泛型

在实际开发中,泛型几乎无处不在,下面介绍几个常用的场景。

List指定集合元素类型:

List<int> list = [];
list.add(1);

list集合指定的类型为 int,只能添加 int 类型数据。

Map<K, V> 指定key、value的类型:

Map<String,int> map = {'key':1,'key1':2};

map 指定key的类型为 String,value的类型为 int

FutureStream 使用泛型,是异步泛型,返回指定类型。FutureStream 完成的时候要么返回指定的类型值要么返回异常。

比如 Future 返回一个 String 类型:

Future<String> fun3() {
  return Future.value('flutter');
}

Stream 使用泛型:

var streamController = StreamController<String>.broadcast();
Stream<Stringget data => streamController.stream;

限制泛型

限制泛型并不是不使用泛型,而是对泛型的类型进行限制,使用 extends 关键字:

定义一个基类:

class DataBase{}

定义 Data 类,此类的泛型需要是DataBase或者其子类:

class Data <T extends DataBase>{}

这里指定了 T 集成 DataBase

定义DataBase子类Person:

class Person extends DataBase{
  String name;
  Person(this.name);
}

那么如下用法是正确的:

var data = Data<Person>();
var data1 = Data<DataBase>();

但是下面的用法是错误的:

var data2 = Data<String>(); //error

class Person1{}
var data3 = Data<Person1>();//error

方法中使用泛型

定义如下方法:获取集合中第2个元素值,集合中元素值为任意类型:

class Data<T{
  T getSecond(List<T> list) {
    return list[1];
  }
}

在类中使用泛型

class DataBase<T{
  T _data;
  T getData(){
    return _data;
  }
}

泛型是非常重要的概念,尤其是写插件和框架的时候。当查看Flutter源码和第三方插件的源码时泛型随处可见。


6b46b37a34c8013955f033834ff345c4.webp你可能还喜欢
关注「老孟Flutter」让你每天进步一点点


浏览 89
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报