一,概述    

     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. security 页面测试

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...

  2. 纯js的右下角弹窗

    <html> <head> <title></title> <meta charset="UTF-8"> <scr ...

  3. mangodb数据库

    阅读目录 一 简介 二 MongoDB基础知识 三 安装 四 基本数据类型 五 CRUD操作 六 可视化工具 七 pymongo 一 简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库1. ...

  4. GPIO软件模拟IIC时序

    一.MPU6050中的IIC时序 1.1 START和STOP SDA和SCL在高电平时,SDA拉低表示START.SCL拉低,表示可以传输数据. SDA和SCL在低电平时,SDA拉高表示STOP. ...

  5. 【Linux】 Centos7 安装 mysql-8.0

    本文介绍使用rpm包安装mysql, 以 mysql-8.0.17-1.el7.x86_64.rpm-bundle.tar 为例: 1.下载 MySQL下载地址:https://dev.mysql.c ...

  6. Linux 下虚拟机——Virtual Box

    下面介绍几款可以在Linux下运行的虚拟机 VMware,VirtualBox, QEMU, Xen.(其中我只用过VirtualBox 和Xen, 我是新手,其他两个没时间折腾,所以下面的资料都几乎 ...

  7. 经典的MySQL Duplicate entry报错注入

    SQL注射取数据的方式有多种: 利用union select查询直接在页面上返回数据,这种最为常见,一个前提是攻击者能够构造闭合的查询. Oracle中利用监听UTL_HTTP.request发起的H ...

  8. 【Java架构:基础技术】一篇文章搞掂:Linux

    基于CentOS 一.安装[暂略] 二.使用和登录[赞略] 三.使用yum CentOS自带yum,这里暂时不介绍安装方式 四.使用yum安装JDK 1.检查系统是否有安装open-jdk rpm - ...

  9. [转载]真正的inotify+rsync实时同步 彻底告别同步慢

    原文链接http://www.ttlsa.com/web/let-infotify-rsync-fast/ 背景我们公司在用inotify+rsync做实时同步,来解决分布式集群文件一致性的问题.但当 ...

  10. 15. Django连接Mysql数据库

    安装PyMySQL,打开cmd, pip install PyMySQL 在.../blog/init.py 目录下添加: import pymysql pymysql.install_as_MySQ ...