Dart泛型详解

一、Dart泛型概述

在 Dart 语言中,泛型是指一个类或方法可以接受不同类型的参数。泛型可以帮助我们更好地封装代码,提高代码的可重用性和安全性。

泛型的基本语法如下:


class ClassName<T> {
  T method(T arg) {
    return arg;
  }
}

其中,<T> 表示泛型类型参数,可以是任何合法的 Dart 标识符。在上面的例子中,我们定义了一个泛型类 ClassName,它有一个泛型方法 method,该方法接受一个泛型参数 arg,并返回该参数。

二、Dart泛型擦除

Dart 通过泛型擦除来实现泛型。泛型擦除是指编译器在编译时会将泛型的具体类型替换为 Object 类型,并在必要时进行强制转换。这就意味着,在运行时无法判断泛型的类型。

示例代码如下:


void main() {
  List<int> list = [1, 2, 3];
  print(list.runtimeType); // 输出:List<int>
  processList(list);
}

void processList(List<Object> list) {
  print(list.runtimeType); // 输出:List<int>
}

在上面的代码中,我们先定义了一个 List<int> 类型的 list,然后将它作为参数传递给了 processList 方法。在 processList 方法中,我们将参数类型定义为 List<Object>,并输出该参数的类型。我们会发现,输出结果为 List<int>,而不是 List<Object>。这是因为在编译时,泛型类型 int 被擦除,list 的实际类型变为 List<Object>。

三、Dart泛型序列化

Dart 通过序列化和反序列化来实现泛型。序列化是指将对象转换为二进制格式或其他格式,以便于存储或传输。反序列化是指将二进制格式或其他格式转换为对象。

在 Dart 中,我们可以使用 json 库来实现泛型序列化。示例代码如下:


import 'dart:convert';

class Person<T> {
  T name;
  int age;

  Map toJson() {
    return {'name': name, 'age': age};
  }

  static Person fromJson(Map json, T Function(dynamic) fromJsonT) {
    return Person<T>()
        ..name = fromJsonT(json['name'])
        ..age = json['age'];
  }
}

void main() {
  var person = Person<String>()
    ..name = '张三'
    ..age = 18;
  var json = jsonEncode(person.toJson());
  print(json); // 输出:{"name":"张三","age":18}
  var decodedJson = jsonDecode(json);
  var decodedPerson = Person.fromJson(decodedJson, (dynamic name) => name.toString());
  print(decodedPerson.name); // 输出:张三
}

在上面的代码中,我们先定义了一个泛型类 Person,通过 toJson 方法将 Person 实例转换为 Map 对象。然后我们将 Map 对象编码为 JSON 字符串,并输出编码结果。接着,我们将 JSON 字符串解码为 Map 对象,并使用 fromJson 方法将 Map 对象转换为 Person 对象。

四、Dart泛型类型限制

Dart 中可以使用 extends 关键字来限制泛型的类型。示例代码如下:


abstract class Animal {
  String getName();
}

class Cat implements Animal {
  String name;
  
  Cat(this.name);
  
  String getName() => name;
}

class Dog implements Animal {
  String name;
  
  Dog(this.name);
  
  String getName() => name;
}

class AnimalList<T extends Animal> {
  final List<T> _animals = [];
  
  void add(T animal) {
    _animals.add(animal);
  }
  
  void printNames() {
    for (var animal in _animals) {
      print(animal.getName());
    }
  }
}

void main() {
  var animalList = AnimalList<Animal>();
  animalList.add(Cat('小花'));
  animalList.add(Dog('旺财'));
  animalList.printNames(); // 输出:小花 旺财
}

在上面的代码中,我们先定义了一个抽象类 Animal,然后定义了两个实现类 Cat 和 Dog,它们都继承自 Animal。接着,我们定义了一个泛型类 AnimalList,它用于存储 Animal 类型的对象。在 AnimalList 的泛型类型参数 T 上使用 extends 关键字,表示 T 只能是 Animal 或 Animal 的子类。在 AnimalList 类中,我们添加了 add 和 printNames 方法,add 方法用于向 _animals 列表中添加 Animal 类型的对象,printNames 方法用于输出 _animals 中所有对象的名称。

五、Dart泛型类型推断

在 Dart 2.0 中,编译器可以根据变量的类型自动推断泛型类型参数。示例代码如下:


void main() {
  var list = <int>[1, 2, 3];
  var index = 2;
  var item = list[index];
  print(item); // 输出:3
  
  var map = <String, int>{
    'one': 1,
    'two': 2,
    'three': 3
  };
  var key = 'two';
  var value = map[key];
  print(value); // 输出:2
}

在上面的代码中,我们先定义了一个类型为 List<int> 的 list,然后定义了一个变量 index,它的值为 2。接着,我们根据 index 取出了 list 中的第三个元素,并将结果赋值给变量 item。由于 list 的类型已经被推断为 List<int>,所以编译器可以自动推断出 item 的类型为 int。同理,我们定义了一个类型为 Map<String, int> 的 map,然后根据 key 取出了 map 中的一个值,并将结果赋值给变量 value,编译器可以自动推断出 value 的类型为 int。

原创文章,作者:PHZJZ,如若转载,请注明出处:https://www.506064.com/n/324409.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
PHZJZPHZJZ
上一篇 2025-01-12 13:03
下一篇 2025-01-13 13:22

相关推荐

  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • Java BigDecimal 精度详解

    一、基础概念 Java BigDecimal 是一个用于高精度计算的类。普通的 double 或 float 类型只能精确表示有限的数字,而对于需要高精度计算的场景,BigDeci…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25

发表回复

登录后才能评论