英文:
variables being changed in 2 different lists in provider when only calling on one list
问题
我有2个列表在一个提供者中。一个是常量主列表,另一个是带有可变变量的空白玩家列表。
以下是反馈到上述列表的类:
class constList {
String teamName;
bool teamSelectedBool;
List<TeamAbilities> AbilitiesList;
constList({required this.teamName, required this.teamSelectedBool, required this.AbilitiesList});
}
class Player1List {
String teamName;
bool teamSelectedBool;
List<TeamAbilities> AbilitiesList;
void AbilityUsedTrue(index) {
AbilitiesList[index].abilityUsed = true;
}
void AbilityUsedFalse(index) {
AbilitiesList[index].abilityUsed = false;
}
void teamSelectedBoolToggle() {
teamSelectedBool = !teamSelectedBool;
}
Player1List({required this.teamName, required this.teamSelectedBool, required this.AbilitiesList});
}
class TeamAbilities {
String abilityName;
bool abilityUsed;
Abilities({required this.abilityName, required this.abilityUsed});
}
当用户从TeamList中选择一个团队时,将调用以下函数,并将主常量列表中的数据复制到空白玩家列表中:
void Player1ListUpdateVariables(constList item) {
Player1List[0].teamName = item.teamName;
Player1List[0].teamSelectedBool = item.teamSelectedBool;
Player1List[0].AbilitiesList = item.AbilitiesList;
notifyListeners();
}
这部分您已经运作正常,数据被复制,所以之后只需要在应用程序中调用Player1List来更改任何变量。
您遇到的问题是在应用程序的后续部分,当用户按下按钮以更改Player1List中的任何abilityUsed布尔值时,它也会更改所选团队的主要常量列表中的布尔值。似乎它们是连接在一起的。我可以看到这一点,因为上面的print语句返回false,而最后的print语句返回true。
您如何停止这一点,并且使得玩家选择一个团队后,常量列表中的数据仅传输到玩家列表一次,然后我有一个不变的常量列表,可以更改所有变量?
非常感谢,任何帮助将不胜感激。
(请注意,由于您要求只提供代码的翻译部分,我只提供了代码的翻译,没有额外的回答或解释。如果需要进一步的解释,请随时提出。)
英文:
I have 2 lists in a provider. A master constant list and a blank player list with variables that change.
List<constList> TeamList = [
constList(
teamName: 'TEAM A',
teamSelectedBool: true,
AbilitiesList: [
TeamAbilites(abilityName: 'ABILITY A', abilityUsed: false),
TeamAbilites(abilityName: 'ABILITY B', abilityUsed: false),
TeamAbilites(abilityName: 'ABILITY C', abilityUsed: false),
],
),
constList(
teamName: 'TEAM B',
teamSelectedBool: false,
AbilitiesList: [
TeamAbilites(abilityName: 'ABILITY 1', abilityUsed: false),
TeamAbilites(abilityName: 'ABILITY 2', abilityUsed: false),
TeamAbilites(abilityName: 'ABILITY 3', abilityUsed: false),
],
),
];
List<UserList> Player1List = [
teamName: '',
teamSelectedBool: false,
AbilitiesList: [],
];
And here are the classes that feed into the above lists:
class constList {
String teamName;
bool teamSelectedBool;
List<TeamAbilities> AbilitiesList;
constList ({required this.teamName, required this.teamSelectedBool, required this.AbilitiesList});
}
class Player1List {
String teamName;
bool teamSelectedBool;
List<TeamAbilities> AbilitiesList;
void AbilityUsedTrue(index) {
AbilitiesList[index].abilityUsed = true;
}
void AbilityUsedFalse(index) {
AbilitiesList[index].abilityUsed = false;
}
void teamSelectedBoolToggle() {
teamSelectedBool= !teamSelectedBool;
}
Player1List ({required this.teamName, required this.teamSelectedBool, required this.AbilitiesList});
}
class TeamAbilities {
String abilityName;
bool abilityUsed;
Abilities ({required this.abilityName, required this.abilityUsed});
}
when a user chooses a team from the TeamList, the below function is called and the data in the master constant list is copied over to the blank player list.
void Player1ListUpdateVariables(constList item) {
Player1List[0].teamName = item.teamName;
Player1List[0].teamSelectedBool = item.teamSelectedBool;
Player1List[0].AbilitiesList= item.AbilitiesList;
notifyListeners();
}
this I have working and the data is being copied over so I then only need to call on Player1List later in the app to change any of the variables.
The problem I'm having is later in the app, when the user presses a button to change any of the abilityUsed bools in the Player1List using the below code:
print(context.read<MyProvider().TeamList[0].AbilitiesList[0].abilityUsed);
context.read<MyProvider>().Player1List[0].AbilityUsedTrue(0);
print(context.read<MyProvider().TeamList[0].AbilitiesList[0].abilityUsed);
it is also changing the bools in the master constant list of the selected team too. As if they were linked. I can see this because print statement above returns false and the last print statement returns true.
how do i stop this and have it so that when the player chooses as team, the data in the constant list is transferred over to the player list only once and then i have a constant list that doesn't change and a player list where I can change all the variables?
thanks so much and any help would be greatly appreciated.
答案1
得分: 1
你遇到的问题在处理引用类型的编程语言中很常见。在Dart中,当你将一个对象(它是引用类型)赋值给另一个变量时,它不会创建该对象的新副本,只是使新变量引用同一个对象。因此,通过一个变量所做的任何更改将在通过另一个变量访问对象时反映出来,因为它们都引用同一个底层对象。
如果你想在Dart中创建一个对象的副本(即“深拷贝”),你必须手动完成。Dart没有内置支持深拷贝,所以你必须创建一个新对象,并手动复制每个属性。以下是如何做到这一点的方法:
void Player1ListUpdateVariables(constList item) {
// 创建一个新的List<TeamAbilities>,其中每个元素都是item.AbilitiesList中相应元素的副本。
var copiedAbilitiesList = item.AbilitiesList.map((ability) =>
TeamAbilities(abilityName: ability.abilityName, abilityUsed: ability.abilityUsed)
).toList();
Player1List[0].teamName = item.teamName;
Player1List[0].teamSelectedBool = item.teamSelectedBool;
Player1List[0].AbilitiesList = copiedAbilitiesList;
notifyListeners();
}
这样,你创建了一个新的List<TeamAbilities>
,其中每个元素都是item.AbilitiesList
中相应元素的副本。然后,当你将这个新列表赋值给Player1List[0].AbilitiesList
时,不管你是否修改其中的TeamAbilities
对象 - 它们与item.AbilitiesList
中的对象是分开的。
英文:
The issue you are encountering is a common one in programming languages that deal with reference types. In Dart, when you assign an object (which is a reference type) to another variable, it doesn't create a new copy of that object, it simply makes the new variable refer to the same object. So, any changes you make via one variable will be reflected when you access the object via the other variable, because they're both referring to the same underlying object.
If you want to create a copy of an object in Dart (i.e., a "deep copy"), you have to do it manually. Dart doesn't have built-in support for deep copying, so you have to create a new object and manually copy over each property. Here's how you can do that:
void Player1ListUpdateVariables(constList item) {
// Create a new List<TeamAbilities> where each element is a copy of the corresponding
// element in item.AbilitiesList.
var copiedAbilitiesList = item.AbilitiesList.map((ability) =>
TeamAbilities(abilityName: ability.abilityName, abilityUsed: ability.abilityUsed)
).toList();
Player1List[0].teamName = item.teamName;
Player1List[0].teamSelectedBool = item.teamSelectedBool;
Player1List[0].AbilitiesList = copiedAbilitiesList;
notifyListeners();
}
This way, you're creating a new List<TeamAbilities>
where each element is a copy of the corresponding element in item.AbilitiesList
. Then, when you assign this new list to Player1List[0].AbilitiesList
, it doesn't matter if you modify the TeamAbilities
objects in it - they're separate from the ones in item.AbilitiesList
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论