Dart 是一种面向对象、静态类型的编程语言,广泛应用于 Flutter 应用开发。在实际开发中,掌握 Dart 的基本数据类型及其操作方法至关重要。本文将系统性地介绍 Dart 中最常用的五类基础数据类型:String 字符串类型int/num/double 数字类型List 列表类型Map 字典类型以及dynamic 动态类型,并结合具体代码示例、运行结果和使用场景进行深入剖析。


一、字符串类型 – String

1. 场景说明

当我们需要用一个变量来描述一段文本内容时,就可以使用 String 类型。例如用户昵称、文章标题、提示信息等,都属于字符串范畴。

2. 基本语法

String 属性名 = '文本内容';

Dart 支持使用单引号 ' '双引号 " " 定义字符串,二者功能完全一致。

3. 特点与高级用法

(1)字符串可变性

Dart 中的 String不可变对象(immutable),但变量本身可以重新赋值:

void main() {
  String aaa = "今天周一";
  print(aaa); // 输出:今天周一
  aaa = "明天周二";
  print(aaa); // 输出:明天周二
}
(2)字符串插值(模板字符串)

Dart 支持使用 ${} 进行字符串插值,可直接嵌入变量或表达式:

String context = "我要在${DateTime.now()}吃早饭";
print(context);
// 示例输出:我要在2026-01-31 15:55:00.123456 吃早饭

⚠️ 注意:如果插入的是简单变量(如 x),可省略花括号写作 $x;若为表达式(如 DateTime.now()),则必须使用 ${}

(3)变量插值示例
String x = '小明';
String s = "小红与$x是好朋友";
print(s); // 输出:小红与小明是好朋友

4. 实际应用场景

  • 显示用户输入的姓名、地址
  • 构建日志信息(如“操作成功于 ${time}”)
  • 拼接 API 请求 URL
  • 国际化文本处理(配合 i18n)

5. 运行效果示意

String 类型运行结果

上图展示了字符串赋值、修改及模板插值的输出结果,清晰体现了 Dart 字符串的灵活性。


二、数字类型 – int / num / double

1. 场景说明

当需要表示数值(如年龄、分数、价格、坐标等)时,需使用数字类型。Dart 提供了三种主要数字类型:

类型 说明
int 整数(如 10, -5, 1000)
double 浮点数(如 3.14, -0.5)
num intdouble 的父类,可表示任意数字

2. 基本语法

int age = 25;
double price = 19.99;
num score = 85.5; // 可赋 int 或 double

3. 类型区别与赋值规则

(1)类型层级关系
  • numintdouble 的公共父类。
  • intdouble 不能互相直接赋值
  • double 可以直接赋值给 num
  • num 不能直接赋值给 intdouble,需显式转换。
(2)正确赋值示例
void main() {
  int s = 10;
  num a = 80.5;
  double c = 90.2;

  // 正确转换方式
  s = a.toInt();       // num → int
  c = s.toDouble();    // int → double
  c = a.toDouble();    // num → double(其实 a 已是 double)
  a = c;               // double → num ✅ 允许
}
(3)错误示例(编译报错)
int x = 5.0;      // ❌ 错误:double 不能直接赋给 int
double y = 10;    // ❌ 错误:int 不能直接赋给 double
num n = 10;
int m = n;        // ❌ 错误:num 不能直接赋给 int

4. 实际应用场景

  • int:用户 ID、计数器、数组索引
  • double:GPS 坐标、商品价格、物理计算
  • num:通用数学函数参数(如 max(num a, num b)

5. 运行效果示意

数字类型运行结果

图中展示了不同类型变量的声明与字符串插值输出,验证了类型系统的严谨性。


三、列表类型 – List

1. 场景说明

当一个变量需要存储多个同类型或不同类型的数据(如一组水果、用户列表、成绩记录)时,应使用 List

2. 基本语法

List<String> fruits = ['苹果', '香蕉', '梨'];
// 或简写(Dart 2.0+ 推荐带泛型)
var fruits = <String>['苹果', '香蕉', '梨'];

💡 强烈建议使用泛型(如 List<String>)以获得更好的类型安全和 IDE 提示。

3. 常用操作方法

(1)添加元素
  • add(item):在末尾添加一个元素
  • addAll(list):在末尾添加整个列表
fruit.add('橙子');
fruit.addAll(['西瓜', '火龙果']);
(2)删除元素
  • remove(item):删除第一个匹配项
  • removeLast():删除最后一个元素
  • removeRange(start, end):删除索引区间(左闭右开)
fruit.remove('梨');          // 删除“梨”
fruit.removeLast();          // 删除最后一个
fruit.removeRange(0, 2);     // 删除索引 0 和 1(不包含 2)
(3)查询与遍历
  • length:获取长度
  • first / last:首尾元素
  • isEmpty:是否为空
  • forEach((item) {}):遍历每个元素
fruit.forEach((item) => print(item));
(4)条件筛选与判断
  • every((item) => bool):是否所有元素满足条件
  • where((item) => bool).toList():筛选满足条件的元素
// 判断是否所有水果都以“西”开头
bool allStartWithXi = fruit.every((item) => item.startsWith('西'));

// 筛选出以“西”开头的水果
List<String> xiFruits = fruit.where((item) => item.startsWith('西')).toList();

4. 实际应用场景

  • 商品购物车(增删改查)
  • 用户消息列表
  • 图表数据源
  • 表格行数据集合

5. 运行效果示意

List 类型运行结果

图中展示了列表的初始化、添加、删除、遍历及条件判断的完整流程。


四、字典类型 – Map

1. 场景说明

当需要通过键(key)快速查找对应的值(value) 时,应使用 Map。典型场景包括:多语言翻译、配置项、用户信息映射等。

2. 基本语法

Map<String, String> fruits = {
  "apple": "苹果",
  "banana": "香蕉"
};

// 或简写
var fruits = <String, String>{
  "apple": "苹果",
  "banana": "香蕉"
};

🔑 键和值均可指定类型,提升代码健壮性。

3. 常用操作方法

(1)取值与赋值
String apple = fruits["apple"]; // 取值(可能为 null)
fruits["orange"] = "橙子";     // 赋值(新增或覆盖)
(2)遍历
fruits.forEach((key, value) {
  print("$key -> $value");
});
(3)增删查清
  • addAll(Map):合并另一个字典
  • containsKey(key):是否包含某键
  • remove(key):删除某键值对
  • clear():清空整个字典
fruits.addAll({"best": "最好"});
print(fruits.containsKey("best")); // true
fruits.remove("best");
fruits.clear(); // {}

4. 实际应用场景

  • 国际化语言包(en → English, zh → 中文)
  • HTTP 响应头解析
  • 用户偏好设置存储
  • 状态码映射(200 → “OK”)

5. 运行效果示意

Map 类型运行结果

图中演示了字典的创建、遍历、添加、查询、删除和清空操作。


五、动态类型 – dynamic

1. 定义与特点

dynamic 是 Dart 中的动态类型关键字,用于声明可在运行时改变类型的变量。

核心特性:
  • 绕过编译时类型检查
  • 允许任意类型赋值
  • 调用任何方法/属性(运行时可能报错)

2. 基本语法

dynamic ss = "你好";
ss = 1;         // ✅ 允许
ss = [1, 2, 3]; // ✅ 允许
ss = null;      // ✅ 允许

3. dynamic 与 var 的区别

特性 dynamic var
类型推断 无,始终为 dynamic 有,根据初始值推断
类型可变性 ✅ 运行时可任意改变 ❌ 推断后类型固定
编译时检查 ❌ 不检查方法/属性是否存在 ✅ 检查
安全性 低(易运行时报错)
使用建议 仅在必要时(如 JSON 解析、反射) 日常开发首选
示例对比:
dynamic d = "hello";
d = 100;
print(d + 1); // ✅ 运行时计算 100 + 1 = 101

var v = "hello";
v = 100; // ❌ 编译错误!v 已被推断为 String

4. 适用场景

  • 解析未知结构的 JSON 数据
  • 与 JavaScript 交互(在 Web 开发中)
  • 反射或元编程
  • 临时调试变量

⚠️ 警告:过度使用 dynamic 会丧失 Dart 的类型安全优势,应尽量避免。


六、总结与最佳实践

类型 推荐使用场景 是否推荐泛型 安全性
String 文本内容
int 整数(ID、计数)
double 小数(价格、坐标)
num 通用数字参数
List<T> 有序集合 ✅ 强烈推荐
Map<K,V> 键值对映射 ✅ 强烈推荐
dynamic 未知类型、JSON 解析

最佳实践建议:

  1. 优先使用具体类型(如 Stringint),而非 dynamic
  2. List 和 Map 务必使用泛型,提升可读性与安全性。
  3. 避免隐式类型转换,使用 .toInt().toDouble() 显式转换。
  4. 字符串拼接优先使用插值 ${},而非 +
  5. 对 Map 取值时注意 null 安全,可使用 ?? 提供默认值:
    String name = userMap['name'] ?? '匿名用户';
    

七、结语

Dart 的类型系统在保持简洁的同时,提供了强大的静态分析能力。熟练掌握 String、数字类型、ListMapdynamic 的特性与使用规范,是编写高效、安全、可维护 Dart 代码的基础。尤其在 Flutter 开发中,这些类型贯穿于 UI 构建、状态管理、网络请求等各个环节。

希望本文能帮助你系统理解 Dart 的核心数据类型,并在实际项目中合理运用,写出更优雅的代码!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐