如何创建列表的副本<;T>;在dart中,当T为对象时,请参见下面的代码

如何创建列表的副本<;T>;在dart中,当T为对象时,请参见下面的代码,dart,flutter,Dart,Flutter,在编辑器中,我在下面键入以测试我的问题 根据我的测试列表,from函数仅在T不是对象/类时创建一个新副本 我测试了list.from for list,它的工作原理类似于魅力,但不是类/对象 请让我知道如何创建代码下方T列表的新副本,以便当我们更改一个位置的列表时,另一个位置不会发生更改 谢谢 void main() { List<Status> statuses = <Status>[ Status(name: 'Confirmed', isCheck: t

在编辑器中,我在下面键入以测试我的问题

根据我的测试列表,from函数仅在T不是对象/类时创建一个新副本

我测试了list.from for list,它的工作原理类似于魅力,但不是类/对象

请让我知道如何创建代码下方T列表的新副本,以便当我们更改一个位置的列表时,另一个位置不会发生更改

谢谢

void main() {
  List<Status> statuses = <Status>[
    Status(name: 'Confirmed', isCheck: true),
    Status(name: 'Cancelled', isCheck: true),
  ];
  print('statuses = ${statuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  //this supposed to create a new list of T but apparently only work for non-object
  List<Status> otherStatuses =  new List<Status>.from(statuses);

  print('otherStatuses= ${otherStatuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

 otherStatuses.singleWhere((x)=>x.name=='Cancelled').isCheck=false;

  print('after the changes only on otherStatuses');
  print('statuses = ${statuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  print('statuses2 = ${otherStatuses.toList().map((x) => x.name + '=' + x.isCheck.toString())}');

  print('why the original status (cancelled) equal to false?');

}


class Status {
  String name;
  bool isCheck;

  Status({
    this.name,
    this.isCheck,
  });
}

void main(){
列表状态=[
状态(名称:“已确认”,isCheck:true),
状态(名称:“已取消”,isCheck:true),
];
打印('statuses=${statuses.toList().map((x)=>x.name+'='+x.isCheck.toString())});
//这本应创建一个新的T列表,但显然只适用于非对象
List otherStatuses=新列表。来自(状态);
打印('otherStatuses=${otherStatuses.toList().map((x)=>x.name+'='+x.isCheck.toString())});
otherStatuses.singleWhere((x)=>x.name==“已取消”).isCheck=false;
打印(“仅在其他状态上进行更改后”);
打印('statuses=${statuses.toList().map((x)=>x.name+'='+x.isCheck.toString())});
打印('statuses2=${otherStatuses.toList().map((x)=>x.name+'='+x.isCheck.toString())});
打印('为什么原始状态(已取消)等于false?');
}
阶级地位{
字符串名;
布尔伊斯切克;
地位({
这个名字,
这是我的支票,
});
}

要创建新元素列表,请使用代码中已用于其他目的的
map()
函数:

List<Status> otherStatuses = statuses.map((status)=>Status(name:status.name, isCheck:status.isCheck)).toList()
List otherStatuses=statuses.map((status)=>status(name:status.name,isCheck:status.isCheck)).toList()

同一问题有不同的解决方案。在会议上,他们还讨论了克隆函数,决定不实现它,并对其进行了讨论

您也可以使用

List<Status> otherStatuses = List<Status>.generate(statuses.length,(i) => Status(name: statuses[i].name , isCheck:statuses[i].isCheck));
List otherStatuses=List.generate(statuses.length,(i)=>Status(name:statuses[i].name,isCheck:statuses[i].isCheck));
关于原因?


您的代码不起作用仅仅是因为新的
其他状态
列表引用了相同的
状态
(s)对象,所以当您更改它时,它也会在原始的
状态
列表中更改,因为它是相同的对象。

很抱歉,也许我编辑了太多,但您的解决方案仍然是
新列表。from(状态)
不起作用。如果你创建了最终字段,那么你就无法更改它们,我想我遗漏了一些东西……你是对的,它需要更多的更改,我将它们添加到原始帖子中。如果你得到了列表的新副本,你就不会得到列表中对象的新副本。没有实现深度集合副本的常规方法,y您必须自己实现列表中元素的副本。我认为这个答案是一种变通方法,但它是有效的,如果T有这么多属性,有没有更好的方法来解决这个问题?当然,我已经简化了实际应用程序中的属性,比这更复杂。@Hendra好吧,我不会使用这个术语“变通办法"。我会用这个术语来表示某种预期会起作用的东西,但实际上不会。这里,您使用的方法是从传递的可迭代元素中构建列表,这些元素通过引用传递,因此它们最终是相同的对象。您需要从传递的元素中锻造一个全新的元素。您决定o它(在映射函数、顶级函数或实例克隆方法中)取决于您。这不起作用。它不应该有绿色复选框。@EliWhittle为什么这么说?这里有一个证明它起作用的例子。