Flutter中的List实现深拷贝deepcopy
问题描述
项目中曾遇到这样的问题,在网络请求回来的分类数据类型为Map< String, List< String>>,暂且称之为_categoryMap;然后点击不同的按钮就把_categoryMap中的 List< String> 数据复制给另外一个List对象,称之为_list1;在赋值之前会先对_list1中的数据执行一次清空操作“_list1.clear();”。
这时候问题就来了,数据为空导致Flutter渲染页面一片空白,最后发现_categoryMap中的数据竟然也被清空了。
出现这个问题,主要在于我们进行赋值操作的时候是一种浅拷贝,导致在执行“_list1.clear();”的时候,把_categoryMap对应的数据一并清空了。
解决办法
既然知道了是浅拷贝出现的问题,那么如何解决这种问题呢?现在给出三种解决方案:
1、直接赋值,赋值前不调用clear()操作
2、重新构造对象,一个一个对象的进行填充
3、使用List自带的generate方法创建出类似于深拷贝的对象
1、直接赋值,赋值前不调用clear()操作
这种方法最为简单,不再调用clear()操作,直接覆盖list中的数据,也可以满足_categoryMap中的数据不被清空的需求
2、重新构造对象,一个一个对象的进行填充
重新构造一个List对象,然后便利_categoryMap[‘id’]取出来的List,对取出来的List再做处理:
如果dynamic类型是String,int这样的基本数据类型,直接赋值就可以;
如果dynamic类型是自定义的class对象,可以根据dynamic,new出来一个新的class对像,进行赋值
类似于这样操作
UserInfo info1 = _categoryMap['id'];
UserInfo info2 = UserInfo(
name = info1.name,
);
3、使用List自带的generate方法创建出类似于深拷贝的对象
重点介绍一下使用generate来构造新的List对象,有关generate的定义是这样子的:
/**
* Generates a list of values.
*
* Creates a list with [length] positions and fills it with values created by
* calling [generator] for each index in the range `0` .. `length - 1`
* in increasing order.
*
* new List<int>.generate(3, (int index) => index * index); // [0, 1, 4]
*
* The created list is fixed-length unless [growable] is true.
*/
factory List.generate(int length, E generator(int index),
{bool growable = true}) {
List<E> result;
if (growable) {
result = <E>[]..length = length;
} else {
result = List<E>(length);
}
for (int i = 0; i < length; i++) {
result[i] = generator(i);
}
return result;
}
使用起来也很简单,只需要实现generate中的两个重要参数:
1、就是必须传入length,就是需要创建多少个List中的对象
2、实现E generator(int index)函数,就能得到类似于deepcopy的对象
具体使用如下:
_goodsList = List<QualitySamplingGoodsModel>.generate(
_categoryListModel?.goods?.length,//要传入的长度,不能大于_categoryListModel.goods的长度,可根据实际需要设置
(int index){//创建新的QualitySamplingGoodsModel,默认系统会主动帮我们创建
return _categoryListModel.goods[index];
},growable: true);
注意点: 一定要主要generate中length的大小和generator(int index)函数,不然会操成数据溢出。