如何在Dart/Flutter中修改复制列表元素且不影响原列表?
Dart中列表拷贝与对象引用的常见误区
你遇到的问题本质是对Dart中对象引用和列表拷贝机制的误解,核心点如下:
问题原因
Dart的列表存储的是对象的引用,而非对象本身。你用List.from(friends)做的是浅拷贝——它只是把friends列表里的引用复制到templist中,并没有创建新的User对象。这意味着:
users[0]、friends[0]、templist[0]指向的是同一个User实例- 修改任意一个列表中对象的
name属性,所有指向该实例的变量都会同步看到变化
看你代码的执行流程:
final u1 = users[0]是把users列表第一个元素的引用赋值给u1,添加到friends后修改friends[0].name,本质就是修改users[0]的nametemplist = List.from(friends)只是复制了friends里的两个引用,所以修改templist[0].name时,users[0]和friends[0]的name也会跟着变
解决方案:深拷贝对象
要实现修改新列表元素不影响原列表,需要为每个User对象创建新实例(深拷贝),而不是复制引用。
步骤1:给User类添加拷贝方法
class User { String name; String age; User({required this.name, required this.age}); // 拷贝构造方法,用于创建新的User实例 User.copy(User other) : name = other.name, age = other.age; }
步骤2:复制列表时创建新对象
把原来的templist = List.from(friends)替换为:
templist = friends.map((user) => User.copy(user)).toList();
或者直接通过构造函数创建新实例:
templist = friends.map((user) => User(name: user.name, age: user.age)).toList();
修改后的完整代码
class User { String name; String age; User({required this.name, required this.age}); User.copy(User other) : name = other.name, age = other.age; } void main() { List<User> users = [ User(name: 'A', age: '43'), User(name: 'B', age: '12'), User(name: 'C', age: '53'), User(name: 'D', age: '22'), ]; List<User> friends = []; List<User> templist = []; final u1 = users[0]; friends.add(u1); friends[0].name = 'AA'; final p2 = users[1]; friends.add(p2); friends[1].name = "BB"; // 深拷贝创建新的User实例 templist = friends.map((user) => User.copy(user)).toList(); templist[0].name = "AAA"; templist[1].name = "BBB"; print("users = ${users.map((u) => u.name).toList()}"); print("friends = ${friends.map((f) => f.name).toList()}"); print("templist = ${templist.map((t) => t.name).toList()}"); }
运行结果
users = [A, B, C, D] friends = [AA, BB] templist = [AAA, BBB]
补充说明Dart的传值/传引用
Dart中所有变量传递都是传值,但对于对象类型,这个"值"是对象在内存中的引用地址。所以:
- 当你把对象赋值给另一个变量,或者添加到列表,传递的是引用的副本,指向同一个对象
- 基本类型(int、String、bool等)是不可变的,修改时会创建新实例,因此不会出现这种引用同步的问题
内容的提问来源于stack exchange,提问作者user22362195
相关产品推荐
相关产品推荐

