克隆是一个对象的副本。一般来说,Clone有两种类型。
让我们在dart中创建一个列表。
List original = [1, 2, 3];
在创建列表对象时,它做了以下事情。
-
为列表创建一个变量,即对象
-
列表数据被存储在内存位置
-
对象(原始)有一个对内存位置的引用
-
浅层克隆。在这个复制过程中,数据存在于相同的内存位置,但创建了两个指向相同内存位置的引用。如果你添加或更新原始列表,变化可以在克隆对象中得到。
-
深度克隆:在克隆过程中,存在两个对象(原始对象和克隆对象)和两个内存位置,每个对象指向不同的内存位置。
如果你添加或更新原始列表,变化不会影响到克隆对象。
如何在dart和flutter中创建一个克隆的列表?
我们有多种方法可以进行浅层和深层克隆。
浅层复制列表
我们有两种方法可以复制引用。
- 赋值对象:在这个例子中,原始列表被赋值(
=)一个新的变量。在这里,修改原始列表在复制的对象中做了改变。
因为赋值运算符允许你用两个对象的引用指向同一个位置。 下面是一个使用赋值运算符的浅层克隆的例子。
void main() {
List original = [1, 2, 3];
var cloned = original;
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 3, 5]
}
- 使用List casteFrom方法。
List casteFrom也会创建一个引用的副本,对原始列表的改变会导致应用原始列表。
下面是一个使用List casteFrom进行浅层复制的例子。
void main() {
List original = [1, 2, 3];
var cloned = List.castFrom(original);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 3, 5]
}
深度复制列表
有多种方法来创建引用以及内存位置的精确拷贝。 在这里,对原始列表的改变不会在被拷贝的对象中得到改变。
- 使用spread operator(...)
传播操作符在dart 2.3版本中引入。传播操作符传播数据,并通过传播数据赋值给一个新的变量。
这是一个使用传播操作符进行深度克隆的例子。
void main() {
List original = [1, 2, 3];
List cloned = [...original];
original.add(5);
print(original); //[1, 2, 3, 5]
print(cloned);//[1, 2, 3]
}
- 使用List addAll方法
在这个例子中,用空数组的addAll()方法将原始列表追加到克隆对象。
原始列表使用add和remove()方法进行添加和删除。然而,克隆对象并没有删除或添加新的元素。
这是一个使用List addAll方法进行深度克隆的例子。
void main() {
List original = [1, 2, 3];
List cloned = []..addAll(original);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- 使用List from方法
List 提供了一个使用 from()方法的命名构造函数,它接受一个动态类型的List。
这是一个使用List from方法进行深度复制的例子。
void main() {
List original = [1, 2, 3];
List cloned = List.from(original);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- List unmodifiable方法:使用immutable(
List unmodifiable method)复制列表,这是一个使用List unmodifiable方法进行深度复制的例子。
void main() {
List original = [1, 2, 3];
var cloned = List.unmodifiable(original);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- List unmodifiable方法:List的方法提供了另一种方法,从现有的列表中创建一个列表的副本。
这是一个使用List of the方法进行深度拷贝的例子。
void main() {
List original = [1, 2, 3];
var cloned = List.of(original);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- 使用List toList方法:List toList方法创建一个原始列表的深度拷贝。
这是一个使用List toList方法进行深度拷贝的例子。
void main() {
List original = [1, 2, 3];
var cloned = original.toList();
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- 使用List generate方法:另一种方法是使用List generate方法创建一个可增长的列表,它创建了两个对象和引用。这是一个使用List generate方法进行深度拷贝的示例代码。
void main() {
List original = [1, 2, 3];
var cloned = List.generate(original.length, (index) => original[index]);
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
- 使用List map方法:最后,使用stream map方法遍历一个原始列表,使用toList()方法将元素流转换成一个列表。
使用List map方法进行深度拷贝的示例代码。
void main() {
List original = [1, 2, 3];
List cloned = original.map((item)=>item).toList();
original.add(5);
original.remove(2);
print(original); //[1, 3, 5]
print(cloned); //[1, 2, 3]
}
总结
总结一下,学习了用浅层和深层克隆的方式来克隆或复制一个对象的多种方法,并举例说明