Flutter复制对象列表后修改副本却影响原列表,是否正常及问题排查
问题解答
这不是bug,是Dart中引用类型的正常表现。
你当前的代码tempHolidays = holidays并没有创建新的列表副本,只是让tempHolidays变量和holidays变量指向了同一个内存地址的列表对象。而且列表中的Holiday实例也是引用类型,所以无论通过哪个变量修改列表里的对象属性,本质上都是在修改同一个实例,自然会同步影响原列表。
要实现修改副本不影响原列表,需要做深拷贝——创建新的列表,同时为每个Holiday对象创建独立的副本:
方法1:给Holiday类添加拷贝构造函数
先在Holiday类中定义一个拷贝构造函数,用于复制对象的所有属性:
class Holiday { DateTime start; DateTime end; Holiday(this.start, this.end); // 拷贝构造函数,注意DateTime也要创建新实例 Holiday.copy(Holiday other) : start = DateTime.fromMillisecondsSinceEpoch(other.start.millisecondsSinceEpoch), end = DateTime.fromMillisecondsSinceEpoch(other.end.millisecondsSinceEpoch); }
然后复制列表:
var tempHolidays = holidays.map((h) => Holiday.copy(h)).toList();
方法2:手动遍历复制
如果不想修改Holiday类,可以手动遍历原列表,逐个创建新的Holiday实例:
var tempHolidays = <Holiday>[]; for (var holiday in holidays) { tempHolidays.add(Holiday( DateTime.fromMillisecondsSinceEpoch(holiday.start.millisecondsSinceEpoch), DateTime.fromMillisecondsSinceEpoch(holiday.end.millisecondsSinceEpoch), )); }
注意:
DateTime也是引用类型,所以必须创建新的DateTime实例,不能直接复用原对象的start/end,否则修改日期时仍会影响原列表。
内容的提问来源于stack exchange,提问作者Lee Casey
相关产品推荐
相关产品推荐

