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

Flutter&Dart:解决使用.add()/.addAll()时参数引用导致全局数据变更问题

问题

我有一个全局参数模板,供需要复制数据以在任意组件中展示的参数使用。部分组件存在修改参数数据的函数,问题在于当使用.add()或.addAll()修改参数数据时,全局参数的数据也会随之改变,涉及的数据类型为List和Map。

示例代码:

dynamic a;
dynamic b;
a = [];
b = a;
print("List");
print("a = $a , b = $b"); //a = [] , b = []
b.addAll([1]);
print("a = $a , b = $b"); //a = [1] , b = [1]
b = [
  ...b,
  ...[2]
];
print("a = $a , b = $b"); //a = [1] , b = [1, 2]

a = {};
b = a;
print("Map");
print("a = $a , b = $b"); //a = {} , b = {}
b.addAll({'1': 1});
print("a = $a , b = $b"); //a = {1: 1} , b = {1: 1}
b = {
  ...b,
  ...{'2': 2}
};
print("a = $a , b = $b"); //a = {1: 1} , b = {1: 1, 2: 2}

如何在使用.add()或.addAll()的前提下解决该问题?


解决方案

核心问题是List和Map都是引用类型,直接赋值b = a只是让变量b指向a的内存地址,修改b的内容本质上是修改同一个对象。要解决这个问题,需要在复制时创建一个全新的副本,而不是引用原对象。

针对List的处理

创建List副本的常用方式:

  • 使用List.from()方法
  • 使用展开运算符[...a]

修改后的示例:

dynamic a;
dynamic b;
a = [];
b = List.from(a); // 或者 b = [...a];
print("List");
print("a = $a , b = $b"); //a = [] , b = []
b.addAll([1]);
print("a = $a , b = $b"); //a = [] , b = [1]
b = [
  ...b,
  ...[2]
];
print("a = $a , b = $b"); //a = [] , b = [1, 2]

针对Map的处理

创建Map副本的常用方式:

  • 使用Map.from()方法
  • 使用展开运算符{...a}

修改后的示例:

dynamic a;
dynamic b;
a = {};
b = Map.from(a); // 或者 b = {...a};
print("Map");
print("a = $a , b = $b"); //a = {} , b = {}
b.addAll({'1': 1});
print("a = $a , b = $b"); //a = {} , b = {1: 1}
b = {
  ...b,
  ...{'2': 2}
};
print("a = $a , b = $b"); //a = {} , b = {1: 1, 2: 2}

注意事项

如果List或Map中包含的是自定义对象(而非基础类型),上面的方式只会做浅拷贝,对象本身还是引用。如果需要完全独立的深拷贝,需要手动实现对象的复制逻辑,比如给自定义类添加copyWith方法,或者编写专门的复制函数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:24:22