上一篇我们说到,实现了copy trait的变量在作用域结束时,触发drop机制。
那为什么实现了copy trait不发触发drop?
copy trait在std::marker中被定义,对它的说明为:实现了此trait的类型按位复制即可轻易获得其值。这里vec作为举例来说明move/clone/copy的区别。
注:vec,一个动态数组,容器。
一个vec动态数组有三个要素:
- len(长度)
- capacity(容量)
- data(指针)
len代表当前数组有多个元素,capacity代表当前数组的容量,data指向了这个空间容量的首地址。
动态数组最特殊的地方在于data/capacity都是会变化的,它能通过缩容和扩容的手段来获得合适的容量来保持复杂度。
它的数据逻辑如下图;
move
当我们通过运算符=将这个vec绑定在一个新变量上,代码如下:
let x = vec![1, 2, 3];
let y = x;//move
此时第二行这里发生的过程叫move;那这个过程是怎么样的?
当第二行执行时,我们说所有权发生了转移。在内存中的转换如图:
- 按位复制
- 转移所有权
当第二行执行时,原本data所指向的数据被禁止,连带着原先整个变量被禁止访问,此时x还存在内存中。
具体例子如下:
let mut x = vec![1, 2, 3];
println!("x:{:p}", &x);
println!("x:{:?}", x);
let y = x;
println!("y:{:?}", y);
println!("y:{:p}", &y);
x = vec![4, 5, 6];
println!("x:{:?}", x);
println!("x:{:p}", &x);
clone
clone trait的解释为:无法轻易按位复制便能获得的值。对于此种类型,我们必须手动实现clone trait。并且这个方法无法使用运算符重载。
vec的clone示意图如下:
clone进行了两次操作。