一,概述    

     Dart是一种可选的类型语言。Dart中的集合默认是异构的。换句话说,单个Dart集合可以托管各种类型的值。但是,可以使Dart集合保持同质值。泛型的概念可以用来实现同样的目的。
  泛型的使用强制限制集合可以包含的值的数据类型。这种集合称为类型安全集合。类型安全是一种编程功能,可确保内存块只能包含特定数据类型的数据。
  所有Dart集合都通过泛型支持类型安全实现。包含数据类型的一对尖括号用于声明类型安全的集合。声明类型安全集合的语法如下所示。
    通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

二,语法

Collection_name <data_type> identifier= new Collection_name<data_type>

三,使用泛型的好处

  泛型是类型安全的(意思是你必须指定数据的类型),但是它的写法比硬编码指定类型高效的多:

  • 类型安全

    比如让数组只有String值,定义为List。这样,后续代码中,如果给数组赋值了非String类型,编译器将提示报错

    var names = List<String>();
    names.addAll(['Seth', 'Kathy', 'Lars']);
    names.add(); // Error
  • 减少重复的代码  
    泛型让你通过一个单一类可以适配多种类型的数据操作,同时可以进行静态代码检查(比如,类型安全检查)。
    abstract class ObjectCache {
    Object getByKey(String key);
    void setByKey(String key, Object value);
    }

    上面代码是对Object类型操作,在没用泛型的情况下,你想对String类型操作,就得重新定义一个类

    abstract class StringCache {
    String getByKey(String key);
    void setByKey(String key, String value);
    }

    后面,你如果相对num类型操作,还得重新定义一个类。

    而泛型就可以解决上面的问题,它通过对类型参数化,实现一个类针对多种数据类型操作的适配。

    abstract class Cache<T> {
    T getByKey(String key);
    void setByKey(String key, T value);
    }

四,Dart泛型的使用

  • 使用集合

    List(通用列表)和map(通用映射)等字面量方式可以用指定类型参数。

    var names = <String>['Seth', 'Kathy', 'Lars'];
    var pages = <String, String>{
    'index.html': 'Homepage',
    'robots.txt': 'Hints for web robots',
    'humans.txt': 'We are people, not machines'
    };

    Set(通用集)和Queue(通用队列)等构造器方式可以用指定类型参数

    void main() {
      List <String> logTypes = new List <String>();
      logTypes.add("WARNING");
      logTypes.add("ERROR");
      logTypes.add("INFO");   // iterating across list
      for (String type in logTypes) {
        print(type);
      }
    }
    import 'dart:collection';
    void main() {
      Queue<int> queue = new Queue<int>();
    print("Default implementation ${queue.runtimeType}");
    queue.addLast();
    queue.addLast();
    queue.addLast();
    queue.addLast();
    queue.removeFirst(); for(int no in queue){
    print(no);
    }
    }
  • Dart的泛型类型是在运行时绑定的,这样,在运行时,可以知道List内具体类型

    var names = List<String>();
    names.addAll(['Seth', 'Kathy', 'Lars']);
    print(names is List<String>); // true

    注意:java中,泛型是采用擦除的方式,它在运行时,其实对象都是Object类型或者泛型的约束父类。

  • 当泛型时,希望限制参数的类型范围,可以用extends关键字约束。
    class Foo<T extends SomeBaseClass> {
    // Implementation goes here...
    String toString() => "Instance of 'Foo<$T>'";
    } class Extender extends SomeBaseClass {...}

    添加约束后,只要是指定的父类或者其子类都可以作为泛型参数。

    var someBaseClassFoo = Foo<SomeBaseClass>();
    var extenderFoo = Foo<Extender>();

    也可以不指定泛型参数。

    var foo = Foo();
    print(foo); // Instance of 'Foo<SomeBaseClass>'

    不可以用限定范围的泛型参数,这样静态代码检查器将提示错误。

    var foo = Foo<Object>();
  • 泛型方法

    下面是允许使用泛型方法的场景:

    In the function’s return type (T).         //返回值
    In the type of an argument (List).        //参数
    In the type of a local variable (T tmp). //局部变量

    T first<T>(List<T> ts) {
    // Do some initial work or error checking, then...
    T tmp = ts[];
    // Do some additional checking or processing...
    return tmp;
    }
  • Dart中泛型用法
    • 泛型方法的用法

      //分类实现:同时支持返回 string类型 和int类型  (代码冗余)
      String getData1(String value){
      return value;
      } int getData2(int value){
      return value;
      } //不确定类型:同时返回 string类型 和number类型 (放弃了类型检查) getData(value){
      return value;
      } //泛系处理:比如:传入number 类型必须返回number类型 传入 string类型必须返回string类型(即减少了代码冗余,又可以检查类型)
      //返回T型
      T getData<T>(T value){
      return value;
      }
      //无返回值
      getData<T>(T value){
      return value;
      }   void main(){
        print(getData<int>());
        }
    • 泛型类的用法

      //案例:把下面类转换成泛型类,要求List里面可以增加int类型的数据,也可以增加String类型的数据。但是每次调用增加的类型要统一
      
       class PrintClass<T>{
      List list=new List<T>();
      void add(T value){
      this.list.add(value);
      }
      void printInfo(){
      for(var i=;i<this.list.length;i++){
      print(this.list[i]);
      }
      }
      } main() {
      PrintClass p=new PrintClass<int>();
      p.add();
      p.add();
      p.printInfo();
      }
    • 泛型接口的用法

      /*
      Dart中的泛型接口:
      实现数据缓存的功能:有文件缓存、和内存缓存。内存缓存和文件缓存按照接口约束实现。
      1、定义一个泛型接口 约束实现它的子类必须有getByKey(key) 和 setByKey(key,value)
      2、要求setByKey的时候的value的类型和实例化子类的时候指定的类型一致
      */ abstract class Cache<T>{
      getByKey(String key);
      void setByKey(String key, T value);
      } class FlieCache<T> implements Cache<T>{
      @override
      getByKey(String key) {
      return null;
      } @override
      void setByKey(String key, T value) {
      print("我是文件缓存 把key=${key} value=${value}的数据写入到了文件中");
      }
      } class MemoryCache<T> implements Cache<T>{
      @override
      getByKey(String key) {
      return null;
      } @override
      void setByKey(String key, T value) {
      print("我是内存缓存 把key=${key} value=${value} -写入到了内存中");
      }
      }
      void main(){
      MemoryCache m=new MemoryCache<Map>();
      m.setByKey('index', {"name":"张三","age":});
      }

        

【Dart学习】-- Dart之泛型的更多相关文章

  1. [dart学习]第四篇:函数和操作符(本篇未完待续)

    接着学习dart的函数和操作符. 1.函数Function dart是一种真正的面向对象的语言,通常一个函数也是Function类型的对象,这也就是说可以把函数赋值给一个变量,或者作为另一个函数的入参 ...

  2. [dart学习]第二篇:dart变量介绍 (一)

    前言 本文的所有内容均是官方文档的简单翻译和理解,需要查看原文,请登录  https://www.dartlang.org/guides/language/language-tour  阅读, 让我们 ...

  3. Dart 学习资料

    Dart 学习资料: 学习资料 网址 Dart 编程语言中文网 http://dart.goodev.org/ Dart 官方包仓库 https://pub.dartlang.org/ 你想了解的Da ...

  4. [dart学习]第五篇:操作符

    前言:本系列内容假设读者有一定的编程基础,如了解C语言.python等. 本节一起来学习dart的操作符,直接拷贝官网的操作符描述表如下: Description Operator unary pos ...

  5. Dart学习笔记-运算符-条件表达式-类型转换

    Dart学习笔记-运算符-条件表达式-类型转换 一.运算符 1.算术运算符 + (加)- (减)* (乘)/ (除)~/ (取整) %(取余) 2.关系运算符 == (等等) != (不等) > ...

  6. 【dart学习】-- Dart之异步编程

    一,概述 编程中的代码执行,通常分为同步与异步两种. 同步:简单说,同步就是按照代码的编写顺序,从上到下依次执行,这也是最简单的我们最常接触的一种形式.但是同步代码的缺点也显而易见,如果其中某一行或几 ...

  7. Dart语言学习( 一) 为什么学习Dart?

    为什么学习Dart? Google及全球的其他开发者,使用 Dart 开发了一系列高质量. 关键的 iOS.Android 和 web 应用. Dart 非常适合移动和 web 应用的开发. 高效 D ...

  8. 简单易懂的Dart》 - Dart语言中文简明教程

    转自:https://www.blackglory.me/straightforward-dart/ Dart是Google公司发布的网络编程语言,其诞生的目的是为了让广大C类OOP程序员们克服Jav ...

  9. [dart学习]第一篇:windows下安装配置dart编译环境,写出helloworld

    前言 博主非科班出身,平时多用C语言,最近想了解学习一门第二语言,看上了可用于移动开发的目前还小众一点dart,准备用一段比较长的时间来慢慢学习.理解. 关于dart语言不再详细介绍了,大家可以访问  ...

随机推荐

  1. linux基础知识-常用命令

    ifconfig :查看当前ip hostname:查看主机名 vim /etc/hosts:修改地址映射 service iptables status : 查看防火墙状态 chkconfig ip ...

  2. 大碗宽面Beta阶段第十一周会议记录

    本周二晚上我们在宿舍楼的大厅进行了本周的小组会议,虽然天气很冷,但大家都还是如数到场,积极参加小组会议.对于上周的任务大家都努力完成,在前端方面,大家完善了主页面和一些分页面,主要有导航栏界面的完成. ...

  3. window10安装mysql-5.7.20-winx64.zip

    window10安装mysql--winx64.zip 原文 https://www.cnblogs.com/ericli-ericli/p/6916285.html D:\share\src\win ...

  4. python基础四(文件操作)

    1.文件操作的基本流程 1.1 文件操作的基本流程 # 绝对路径 # r"d:/葫芦娃.txt 前面的r 为转义. linux平台和windows的分隔符不同 f = open(r" ...

  5. VMware 克隆 CenterOS 虚拟机

    前面介绍了VMware 安装CenterOS 6.9,现在再介绍下 VMware 克隆虚拟机,克隆虚拟机可以快速的创建虚拟机,免去重复安装的烦恼. 一.VMware 克隆 CenterOS 虚拟机 选 ...

  6. jQuery Mobile 自定义导航条图标

    1.jQuery Mobile 自定义导航条图标

  7. Git命令操作

    安装配置 将其bin目录添加到path ssh -keygen -t rsa -C 自己的邮箱(获取ssh远程连接秘钥) 使用: 进入项目目录 右击进入git bash 执行git init gith ...

  8. Oracle 表空间详解

    目录 目录 表空间概述 表空间的分类 默认表空间 查看默认的永久表空间 查看默认的TEMP表空间 查看默认的表空间类型 逻辑结构到物理结构的映射 对表空间的操作 查看表空间使用情况 查看数据库拥有的表 ...

  9. Windows IO System

    Windows IO System是由一些executive components组成,这些component可以认为是ntoskrnl.exe中相对独立的一些module. 整个IO System是 ...

  10. vue-cesium中经纬度写反了,报错

    vue-cesium中经纬度写反了,报错 [Vue warn]: Invalid prop: custom validator check failed for prop "position ...