Vec<i32>和Vec<Box<i32>>有什么区别?

11
let vec1 = vec![1, 2, 3, 4];
let vec2 = vec![Box::new(1), Box::new(2), Box::new(3), Box::new(4)];
他们之间有什么区别?我已经在堆上分配了vec1,那么vec1的所有元素不也在堆上吗?为什么我还需要像在vec2中一样单独在堆上分配它们呢?

2
我不是 Rust 专家,但我认为区别在于 1 是值为 1 的变量,而 ~1 则是指向 1 的拥有所有权的指针。因此,在 vec2 中,您只是获得了一个更高级别的间接引用。 - Paolo Falabella
2个回答

32

我将绘制一张图表。第一个值是指向堆上连续数字数组的指针。

(stack)    (heap)
┌──────┐   ┌───┐
│ vec1 │──→│ 1 │
└──────┘   ├───┤
           │ 2 │
           ├───┤
           │ 3 │
           ├───┤
           │ 4 │
           └───┘

第二个版本添加了额外的间接性。元素仍然在堆上,但现在它们在堆的其他位置。

(stack)    (heap)   ┌───┐
┌──────┐   ┌───┐ ┌─→│ 1 │
│ vec2 │──→│   │─┘  └───┘
└──────┘   ├───┤    ┌───┐
           │   │───→│ 2 │
           ├───┤    └───┘
           │   │─┐  ┌───┐
           ├───┤ └─→│ 3 │
           │   │─┐  └───┘
           └───┘ │  ┌───┐
                 └─→│ 4 │
                    └───┘

由于Rust中所有权的工作方式,您不会遇到任何语义差异。额外的间接性会导致更差的内存使用和缓存局部性。


8
那是一个非常令人印象深刻的图表。您花了多长时间打出来? - Lily Ballard
7
不是很长,我只是复制并粘贴方框绘图字符周围。 - Dietrich Epp

4

vec![1, 2, 3, 4] 是由 i32 类型组成的向量。

vec![Box::new(1), Box::new(2), Box::new(3), Box::new(4)] 是由指向 i32 类型的所有权指针组成的向量。Rust 的所有权指针类似于 C++ 的 unique_ptr。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接