我有以下颤振代码,我有一个列表,我们称之为list1
,我将这个列表的值对应到另一个列表list2
。
当我从list1
中删除一个元素时,它会自动从list2
中删除!
有一个最小的代码来重现这个问题。我无法理解这种奇怪的行为,有人能向我解释一下吗?
我想做的是从list1
中删除一个项目,但保持list2
原样。
这是代码:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(EmptyFile());
class EmptyFile extends StatefulWidget {
final list1 = ["1", "2", "3"];
EmptyFile({Key? key}) : super(key: key);
@override
_EmptyFileState createState() => _EmptyFileState(list1);
}
class _EmptyFileState extends State<EmptyFile> {
List<String> list1 ;
List<String> list2 = [];
_EmptyFileState(this.list1) {
list2 = list1;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Example App'),
),
body:
Container(
child: RaisedButton(
onPressed: () {
print("list1.last ${list1.last}"); // the result is: list1.last 3
list2.remove("3"); // here I delete from list2 (list TWO)
print("list1.last ${list1.last}"); // the result is: list1.last 2 . Here an item from list ONE has been deleted!!!
},
child: Text('delete last Item'),
),
)
));
}
}
您可以从这里在线运行代码:https://dartpad.dev/81d0a66ac7c46258df7847fdc7a10e96?null_safety=true
显然,dart通过引用复制列表。因此,要将一个列表的值复制到另一个列表,请使用以下代码:
list2 = List.from(list1);
而不是:
list2 = list1;
通过此
list2 = list1;
您实际上并不是在复制list1
。这也是分配给list2
的相同列表。
所以你需要改变这个。
list2 = [...list1];
我也遇到过同样的问题。我在GetX状态管理的帮助下从api获取嵌套对象数据。
Hasan Mhd Amin给出的公认答案是绝对正确的。但在嵌套对象(列表的嵌套列表(中没有按需工作。
留意MyCode
List<BrandWithModel> original = [];
List<BrandWithModel> selectedModels = [];
// controllers
final generalController = Get.find<GeneralController>();
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(
(_) {
if (generalController.isRefreshForBrandWithModel.value) {
generalController.brandWithModel(brandIDs: [3, 4]).then(
(value) => initValues(),
);
} else {
initValues();
}
},
);
super.initState();
}
void initValues() {
original = List<BrandWithModel>.from(generalController.models);
selectedModels = List<BrandWithModel>.from(generalController.models);
// remove model from selectedModels
selectedModels.forEach(
(element) {
element.model.clear();
},
);
if (mounted) setState(() {});
}
当我从selectedModels中删除数据时,它也将从原始模型中删除。
经过深入研究,我发现了这一点。
/*
* => When you create a new list using List<BrandWithModel>.from(generalController.models),
* it creates a new list object, but the individual elements within the list are still references to the same objects in memory.
* Therefore, modifying an element in selectedModels will also affect the corresponding element in original because they are essentially the same object.
* => If you want to have separate lists with independent data,
* you need to create new instances of BrandWithModel objects for selectedModels.
* One way to achieve this is by creating a deep copy of each element when initializing the selectedModels list.
* Here's an example of how you can modify the initValues() method to create a deep copy
*/
我在那里找到了如下的解决方案
//Used this
selectedModels = generalController.models
.map(
(model) => BrandWithModel.fromJson( // json to modelmethod
model.toJson(), // model to json method
),
)
.toList();
// instead of
selectedModels = List<BrandWithModel>.from(generalController.models);
// remain are same as above.
您可以使用排列操作:
list2 = [...list1];
这应该允许任何可迭代对象复制值,而不是使用引用。