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
相关产品推荐
相关产品推荐

