You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中List直接赋值与使用...扩展运算符拷贝列表的区别

两种Dart列表赋值写法的核心差异

两种写法的本质区别就是「引用同个对象」和「创建新对象」的区别,没有复杂概念:

1. 直接赋值 List newData = data;

这行代码没有做任何拷贝操作,只是让newData和data两个变量指向内存里完全相同的同一个列表实例。
你对任意一个变量做列表层面的修改——比如增删元素、重新排序、清空列表,两个变量读到的结果都会同步变化,本质上操作的从来都是同一个对象。

List data = [1, 2, 3];
List newData = data;
newData.add(4);
print(data); // 输出 [1, 2, 3, 4],原列表被同步修改

2. 展开运算符赋值 List newData = [...data];

这里的...是Dart的集合展开运算符,这行代码会创建一个全新的空列表,再把原data里的所有元素按顺序挨个塞进新列表里,最终newData和data是两个完全独立的列表实例。
这时候你对newData做增删元素、重排、清空这类列表层面的操作,完全不会影响到原data。

List data = [1, 2, 3];
List newData = [...data];
newData.add(4);
print(data); // 输出 [1, 2, 3],原列表不受任何影响
print(newData); // 输出 [1, 2, 3, 4]

必须注意的浅拷贝坑

展开运算符实现的是浅拷贝,不是深拷贝。
拿你示例里存Map的列表来说:新列表只是把原列表里存的元素引用抄了一遍,列表里装的那些Map对象本身还是同一份。如果你修改新列表里嵌套对象的属性,原列表里对应的值还是会同步变:

List data = [
  {'value': 'value one'},
  {'value': 'value two'},
];
List newData = [...data];
// 修改新列表里嵌套Map的属性
newData[0]['value'] = 'modified';
print(data[0]['value']); // 输出 modified,原列表的嵌套对象还是被改了

如果需要完全不互相影响的深拷贝,得手动遍历列表,把每一层的嵌套对象也都拷贝一份,单靠展开运算符做不到。

选型参考

  • 只是给现有列表起个别名,不需要独立修改新列表的结构,直接用=赋值就行,没有额外性能开销
  • 需要基于原列表生成独立的新列表,做增删、排序等操作不影响原数据,就用...展开(List.of(data)、data.toList()和它的效果完全一致)
  • 存在嵌套对象、需要完全隔离修改影响,自行实现深拷贝逻辑

内容的提问来源于stack exchange,提问作者CCP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:21:35