Flutter---泛型

在 Dart 中,泛型(Generics)是一种强大的编程特性,它允许你编写可以处理多种数据类型的代码,同时保持类型安全。

当没有泛型的时候

Dart 复制代码
// 只能存储字符串的列表
class StringList {
  List<String> items = [];
  
  void add(String item) {
    items.add(item);
  }
  
  String get(int index) {
    return items[index];
  }
}

// 只能存储整数的列表  
class IntList {
  List<int> items = [];
  
  void add(int item) {
    items.add(item);
  }
  
  int get(int index) {
    return items[index];
  }
}
// 需要为每种类型创建单独的类,代码重复!

使用泛型解决代码重复问题

Dart 复制代码
// 通用的列表类,可以存储任何类型
class GenericList<T> {
  List<T> items = [];
  
  void add(T item) {
    items.add(item);
  }
  
  T get(int index) {
    return items[index];
  }
}

void main() {
  // 存储字符串
  var stringList = GenericList<String>();
  stringList.add("Hello");
  stringList.add("World");
  print(stringList.get(0)); // 类型安全:知道返回的是String
  
  // 存储整数
  var intList = GenericList<int>();
  intList.add(1);
  intList.add(2);
  print(intList.get(0)); // 类型安全:知道返回的是int
}

语法理解

Dart 复制代码
// T 是类型参数,可以是任何标识符
class ClassName<T> {
  T value;
  
  ClassName(this.value);
  
  T getValue() {
    return value;
  }
}

// 多个类型参数
class Pair<K, V> {
  K key;
  V value;
  
  Pair(this.key, this.value);
}

泛型可以用于集合中List,Set和Map类型的参数化。对于List或Set,只需要在声明语句前添加类型前缀;对于Map,则需要在声明语句前添加<keyType,valueType>类型前缀。

1.List不用泛型

Dart 复制代码
void main() {
  // 创建一个列表,但不指定类型
  List names = ['Alice', 'Bob', 'Charlie']; // 什么都能放
  
  names.add('David');    // ✅ 可以加字符串
  names.add(123);        // ✅ 也可以加数字(但这样容易出错!)
  names.add(true);       // ✅ 还可以加布尔值
  
  // 使用时不知道是什么类型,容易出错
  String firstPerson = names[0]; // ❌ 运行时可能出错,因为不知道names[0]是不是字符串
  print(firstPerson.toUpperCase()); // 如果names[0]是数字,这里就会崩溃!
}

List使用泛型

Dart 复制代码
void main() {
  // 创建一个只能放字符串的列表
  List<String> names = ['Alice', 'Bob', 'Charlie'];
  
  names.add('David');    // ✅ 可以加字符串
  // names.add(123);     // ❌ 编译时就报错!不能加数字
  // names.add(true);    // ❌ 编译时就报错!不能加布尔值
  
  // 使用时很安全,知道一定是字符串
  String firstPerson = names[0]; // ✅ 安全,知道肯定是字符串
  print(firstPerson.toUpperCase()); // ✅ 不会出错
}

2.Map不使用泛型

Dart 复制代码
void main() {
  // 创建一个Map,但不指定键值类型
  Map student = {
    'name': 'Alice',
    'age': 20,
    'score': 95.5
  };
  
  student['height'] = 165;     // ✅ 可以添加
  student[123] = 'test';       // ✅ 键可以是数字(混乱!)
  student['name'] = 999;       // ✅ 把名字改成数字(不对!)
  
  // 使用时很困惑
  String name = student['name']; // ❌ 可能出错,因为name可能不是字符串
  int age = student['age'];      // ❌ 可能出错
}

Map使用泛型

Dart 复制代码
void main() {
  // 创建一个Map,键必须是字符串,值可以是任意类型
  Map<String, dynamic> student = {
    'name': 'Alice',      // 值:字符串
    'age': 20,            // 值:数字
    'score': 95.5         // 值:小数
  };
  
  student['height'] = 165;     // ✅ 可以添加
  // student[123] = 'test';    // ❌ 编译错误!键必须是字符串
  // student['name'] = 999;    // ❌ 编译错误!名字应该是字符串
  
  // 使用时很清楚
  String name = student['name']; // ✅ 安全
  int age = student['age'];      // ✅ 安全
}
相关推荐
克喵的水银蛇6 小时前
Flutter 动画实战:基础动画 + Hero 动画 + 自定义动画
flutter
松☆8 小时前
Flutter + OpenHarmony 实战:构建离线优先的跨设备笔记应用
笔记·flutter
_大学牲10 小时前
Flutter 勇闯2D像素游戏之路(一):一个 Hero 的诞生
flutter·游戏·游戏开发
kirk_wang10 小时前
Flutter插件在鸿蒙端的开发与部署:跨生态桥梁的架构与实现
flutter·移动开发·跨平台·arkts·鸿蒙
勇气要爆发13 小时前
【第五阶段—高级特性和框架】复杂动画案例分析初体验
flutter
勤劳打代码14 小时前
追本溯源 —— SetState 刷新做了什么
flutter·面试·性能优化
松☆16 小时前
OpenHarmony 后台任务与 Flutter 生命周期协调:构建稳定可靠的混合应用
flutter
松☆16 小时前
Flutter 与 OpenHarmony 深度集成:自定义 MethodChannel 插件开发全指南
flutter·wpf
克喵的水银蛇16 小时前
Flutter 布局实战:掌握 Row/Column/Flex 弹性布局
前端·javascript·flutter