向量的所有权转移会改变它在 Rust 中的内存位置吗?

Jav*_*cal 2 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);
}
Run Code Online (Sandbox Code Playgroud)

和输出

The address of vector v1 is 0x7fff253de570
The address of vector v2 is 0x7fff253de5e0
The address of vector v1 is 0x7fff253de570
Run Code Online (Sandbox Code Playgroud)

为什么值v1v2不一样?

  1. 首先,&v2真的不是vec![1,2,3]在第 2 行中声明的向量地址吗?
  2. 如果值v1复制v2的话,应该不是矢量有一个副本特质?
  3. 如果 的值v1被移动到由 标识的新内存位置v2,为什么完全需要它,为什么v2不简单地指向 的内存位置v1,因为所有权已经转移到v2,并且v1几乎没有用,直到我将它分配回来(简而言之,如果它是内存副本,为什么所有权转移需要一个memcpy?)
  4. 什么时候v1再分配到v2,我怎么得到相同的地址位置?

Jmb*_*Jmb 5

你混淆了数据的地址和变量的地址。一开始,你的记忆看起来像这样:

    Stack               Heap
+----+------+---+       +---+---+---+
|    | len  | 3 |   +-->| 1 | 2 | 3 |
| v1 +------+---+   |   +---+---+---+
|    | data     |---+
+----+------+---+
|    | len  | _ |
| v2 +------+---+
|    | data     |
+----+----------+
Run Code Online (Sandbox Code Playgroud)

完成后let v2 = v1,它看起来像这样:

    Stack               Heap
+----+------+---+       +---+---+---+
|    | len  | _ |   +-->| 1 | 2 | 3 |
| v1 +------+---+   |   +---+---+---+
|    | data     |   |
+----+------+---+   |
|    | len  | 3 |   |
| v2 +------+---+   |
|    | data     |---+
+----+----------+
Run Code Online (Sandbox Code Playgroud)

注意的位置v1,并v2没有改变,并且都没有堆上的数据的位置,但值字段v1已移动到v2。此时,字段的值v1无效。

然后当你这样做时v1 = v2,你会回到第一个配置。

OTOH 您的println语句打印变量的地址v1v2在堆栈上。

请注意,如果您打印&v1[0](resp. &v2[0]),您将获得堆上数据的地址,并看到它没有改变(操场