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

如何基于对象类型数据创建独立新变量,修改不影响原变量

解决对象深拷贝问题:修改新变量不影响原变量

你的问题本质是浅拷贝导致的引用共享——虽然创建了新的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:30:47