如何基于对象类型数据创建独立新变量,修改不影响原变量
解决对象深拷贝问题:修改新变量不影响原变量
你的问题本质是浅拷贝导致的引用共享——虽然创建了新的Data实例,但mainData.data和newData.data指向的是同一个列表,列表里的Group、Weapon对象也都是同一个引用,所以修改新对象的属性会同步影响原对象。要解决这个问题,必须实现深拷贝,让新对象的所有嵌套对象都是独立的新实例。
解决方案:给每个模型类实现深拷贝方法
给Data、Group、Weapon分别添加深拷贝的构造方法,确保创建新对象时,所有嵌套的列表和对象都被重新实例化。
修改后的模型类代码
class Data { List<Group>? data; Data({this.data}); // 深拷贝构造方法 Data.fromDeepCopy(Data original) { if (original.data != null) { // 遍历原列表,每个Group都深拷贝 data = original.data!.map((group) => Group.fromDeepCopy(group)).toList(); } } } class Group { int? id; List<Weapon>? weaponItems; String? groupName; Group({this.id, this.weaponItems, this.groupName}); // 深拷贝构造方法 Group.fromDeepCopy(Group original) { id = original.id; groupName = original.groupName; if (original.weaponItems != null) { // 遍历原武器列表,每个Weapon都深拷贝 weaponItems = original.weaponItems!.map((weapon) => Weapon.fromDeepCopy(weapon)).toList(); } } } class Weapon { int? id; String? name; Weapon({this.id, this.name}); // 深拷贝构造方法 Weapon.fromDeepCopy(Weapon original) { id = original.id; name = original.name; } }
修改main函数的对象创建方式
不再直接传递原列表引用,而是用深拷贝构造方法创建新对象:
void main() { final Data mainData = Data( data: [ Group( id: 1, groupName: 'Assault Riffle', weaponItems: [ Weapon(id: 1, name: 'Ak47'), Weapon(id: 2, name: 'M4'), ], ), Group( id: 2, groupName: 'SMG', weaponItems: [ Weapon(id: 3, name: 'MP5'), Weapon(id: 4, name: 'Dual UZI'), ], ), ], ); // 使用深拷贝构造方法创建新对象 final Data newData = Data.fromDeepCopy(mainData); print('before mainData: ${mainData.data?[0].weaponItems?[0].name}'); // 输出:before mainData: Ak47 newData.data?[0].weaponItems?[0].name = 'SCAR'; print('newData: ${newData.data?[0].weaponItems?[0].name}'); // 输出:newData: SCAR print('after mainData: ${mainData.data?[0].weaponItems?[0].name}'); // 输出:after mainData: Ak47(符合预期) }
原理说明
Data.fromDeepCopy:遍历原data列表,为每个Group创建深拷贝实例,生成全新的列表Group.fromDeepCopy:复制基础属性的同时,遍历原weaponItems列表,为每个Weapon创建深拷贝实例,生成全新的武器列表Weapon.fromDeepCopy:复制id和name属性,创建独立的新Weapon实例
这样所有层级的对象都是独立的引用,修改新对象的属性就不会影响原对象了。
内容的提问来源于stack exchange,提问作者Septian Dika
相关产品推荐
相关产品推荐

