如何用对象A重置复杂对象B?Dart代码中用户列表未同步刷新问题排查
问题分析与解决方案
你遇到的问题核心在于浅拷贝(Shallow Copy)和引用类型的特性,咱们一步步拆解清楚:
为什么用户信息没刷新?
Dart 里的 List.from() 方法处理引用类型(比如你定义的 User 类)时,只会复制列表中对象的内存引用地址,而不是创建全新的 User 实例。也就是说:
- 当你执行
b.users = List<User>.from(a.users!);时,b.users里的User对象和a.users里的是同一个内存地址的对象 - 所以你修改
b.users![0].name = 'Doe'时,其实是直接修改了a.users里那个User对象的name属性 - 后续调用
resetTask(a)时,你只是把a.users的引用再次复制给b.users,但此时a里的User的name已经是Doe了,自然输出的还是Doe
解决方法:实现深拷贝
要让 b 的 users 列表和 a 的完全独立,需要做深拷贝——为每个 User 创建新的实例,而不是复制引用。修改 resetTask 方法里的列表复制逻辑即可:
void main() { Task a = Task(id: 1, title:'task 1', users: [User(id:0, name:'John')]); Task b = Task(id: a.id, title: a.title, users: List<User>.from(a.users!)); resetTask(Task task) { b.id = task.id; b.title = task.title; // 替换成深拷贝:为每个User创建新实例 b.users = task.users!.map((user) => User(id: user.id, name: user.name)).toList(); } print(b.title); // task 1 print('${b.users![0].name} \n'); // John b.title = 'task 2'; b.users![0].name = 'Doe'; print(b.title); // task 2 print('${b.users![0].name} \n'); // Doe resetTask(a); print(b.title); // task 1 print('${b.users![0].name} \n'); // John } class Task { Task({this.id, this.title, this.users}); int? id; String? title; List<User>? users; } class User { User({this.id, this.name}); int? id; String? name; }
验证结果
修改后运行代码,控制台输出会完全符合你的预期:
task 1 John task 2 Doe task 1 John
内容的提问来源于stack exchange,提问作者rigorousCode
相关产品推荐
相关产品推荐

