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

如何在Dart/Flutter中正确复制列表/对象避免联动修改

问题原因

你遇到的是浅拷贝与深拷贝的差异问题。你之前尝试的所有列表复制方式都属于浅拷贝,仅创建了新的列表容器,列表内存储的仍然是原对象的内存引用——两个列表指向内存中同一批对象,修改任意一个列表内的对象属性,另一个列表的对应内容自然会同步变更。

你之前的操作具体差异如下:

  • list_2 = list_1:连新列表都未创建,只是给原列表多绑定了一个变量名,修改列表本身的增删操作也会同步
  • List.of(list_1)、扩展运算符[...list_1]、toList()、循环add元素:仅生成了新的列表结构,内部存储的对象还是和原列表完全一致的引用,只会隔离列表本身的增删操作,不会隔离对象属性的修改
解决方法

你需要对列表内的每个自定义对象单独做深拷贝,也就是为每个对象生成全新的副本,再将副本存入新列表。

步骤1:给自定义类增加拷贝方法

假设你列表存储的是自定义的用户输入类,给类新增copyWith方法,用于生成新的同类对象:

class UserInput {
  String content;
  int type;
  // 假设还有其他自定义属性
  UserInput({required this.content, required this.type});

  // 拷贝方法,不传参数就返回完全相同的新对象,传参数可覆盖对应属性
  UserInput copyWith({
    String? content,
    int? type,
  }) {
    return UserInput(
      content: content ?? this.content,
      type: type ?? this.type,
    );
  }
}

如果你的类还嵌套了其他自定义类,嵌套的类也需要实现对应的copyWith方法,在父类的copyWith中同步调用嵌套类的拷贝方法即可。

步骤2:生成深拷贝的新列表

拷贝列表时,遍历每个元素调用copyWith生成新对象,再存入新列表:

// 写法1:用map遍历生成
List<UserInput> list_2 = list_1.map((item) => item.copyWith()).toList();

// 写法2:用for循环实现,和你之前的写法逻辑一致,仅新增拷贝对象的步骤
List<UserInput> list_2 = [];
for (var item in list_1) {
  list_2.add(item.copyWith());
}

修改完成后再修改list_1内的对象属性,list_2的内容就不会再同步变更了。

补充说明

如果你的列表存储的是int、String、bool等基础数据类型,不需要做深拷贝,浅拷贝就可以满足需求,深拷贝仅针对自定义类对象的列表生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:45:02