向量的所有权转移会改变它在Rust中的内存位置吗?
考虑以下代码片段:
fn main() {
let mut v1 = vec![1, 2, 3];
println!("The address of vector v1 is {:p}", &v1);
let v2 = v1;
println!("The address of vector v2 is {:p}", &v2);
v1 = v2;
println!("The address of vector v1 is {:p}", &v1);
}
和输出
The address of vector v1 is 0x7fff253de570
The address of vector v2 is 0x7fff253de5e0
The address of vector v1 is 0x7fff253de570
为什么值v1和v2不一样?
- 首先,
&v2真的不是vec![1,2,3]在第 2 行中声明的向量地址吗? - 如果值
v1被复制到v2的话,应该不是矢量有一个副本特质? - 如果 的值
v1被移动到由 标识的新内存位置v2,为什么完全需要它,为什么v2不简单地指向 的内存位置v1,因为所有权已经转移到v2,并且v1几乎没有用,直到我将它分配回来(简而言之,如果它是内存副本,为什么所有权转移需要一个memcpy?) - 什么时候
v1再分配到v2,我怎么得到相同的地址位置?
回答
你混淆了数据的地址和变量的地址。一开始,你的记忆看起来像这样:
Stack Heap
+----+------+---+ +---+---+---+
| | len | 3 | +-->| 1 | 2 | 3 |
| v1 +------+---+ | +---+---+---+
| | data |---+
+----+------+---+
| | len | _ |
| v2 +------+---+
| | data |
+----+----------+
完成后let v2 = v1,它看起来像这样:
Stack Heap
+----+------+---+ +---+---+---+
| | len | _ | +-->| 1 | 2 | 3 |
| v1 +------+---+ | +---+---+---+
| | data | |
+----+------+---+ |
| | len | 3 | |
| v2 +------+---+ |
| | data |---+
+----+----------+
注意的位置v1,并v2没有改变,并且都没有堆上的数据的位置,但值字段的v1已移动到v2。此时,字段的值v1无效。
然后当你这样做时v1 = v2,你会回到第一个配置。
OTOH 您的println语句打印变量的地址v1并v2在堆栈上。
请注意,如果您打印&v1[0](resp. &v2[0]),您将获得堆上数据的地址,并看到它没有改变(操场)