Dart中myList.where()是否为引用类型?原列表为何被修改?
Dart中List.where()修改原列表对象的问题及解决方案
问题原因
核心问题是Dart的引用类型传递机制:
List.where()方法返回的是原列表中符合条件元素的迭代器,调用toList()后生成的新列表里,存放的依然是原Product对象的引用,而非新创建的对象副本。Product作为自定义类属于引用类型,修改updateProduct中对象的属性时,本质是在操作原列表里对应对象的内存地址,自然会同步影响allProducts的内容。
解决方案:创建对象独立副本
要彻底隔离原列表和新列表,需要为Product类实现复制方法,生成对象的独立副本,而非仅复制引用。常用方式是实现copyWith方法:
步骤1:为Product类添加copyWith方法
enum PurchaseType { HOUSE, CAR } class Product { final PurchaseType purchaseType; String? someId; Product({required this.purchaseType, this.someId}); // 生成新的Product对象副本 Product copyWith({ PurchaseType? purchaseType, String? someId, }) { return Product( purchaseType: purchaseType ?? this.purchaseType, someId: someId ?? this.someId, ); } }
步骤2:过滤时生成对象副本
修改过滤逻辑,对每个符合条件的Product调用copyWith生成新对象后再组成列表:
List<Product> updateProduct = allProducts .where((p) => p.purchaseType == PurchaseType.HOUSE) .map((p) => p.copyWith()) // 生成原对象的独立副本 .toList();
此时updateProduct中的元素都是全新的Product实例,修改它们的属性不会对原allProducts列表产生任何影响。
补充说明
如果Product类包含嵌套的引用类型属性(比如其他自定义类对象),需要在copyWith中对嵌套对象也执行拷贝操作,实现深拷贝;若仅包含基本类型、枚举等值类型,上述浅拷贝方式即可满足需求。
内容的提问来源于stack exchange,提问作者iKK
相关产品推荐
相关产品推荐

