以下三种声明之间有什么不同?
let a = [1, 2, 3];
let b = &[1, 2, 3];
let c = vec![1, 2, 3];
我理解vec![]
的用法,但什么情况下应该使用[]
和&[]
呢?
以下三种声明之间有什么不同?
let a = [1, 2, 3];
let b = &[1, 2, 3];
let c = vec![1, 2, 3];
我理解vec![]
的用法,但什么情况下应该使用[]
和&[]
呢?
虽然这是你开始阅读Rust文档或《Rust Book》时应该尽快找到的基本信息,这里是一些快速解释:
let a = [1, 2, 3]
是一个包含3个元素的数组,完全驻留在栈中。
stack:
+-----------+
| 1 | 2 | 3 |
+-----------+
let b = &[1, 2, 3]
是对一个在堆栈中也有三个元素的数组的引用:
stack:
+-----------+
| 1 | 2 | 3 |
+-----------+
^
+---+ |
pointer: | * |---|
+---+
如果您将其更改为let b: &[u32] = &[1,2,3]
,b
将不仅仅是一个数组的引用,而是一个 slice,因为Rust会执行Deref coercion。slices是引用,还存储它们指向的长度(这种引用称为fat-pointers):
stack:
+-----------+
| 1 | 2 | 3 |
+-----------+
^
+---+ |
pointer: | * |---|
+---+
length: | 3 |
+---+
let c = vec![1, 2, 3]
是一个动态分配的向量,也就是说它的数据存储在堆中以便能够在运行时改变其大小,但是它会在栈中存储指向堆数据的引用、向量的长度和容量:
stack: heap:
+---+ +-----------+---+
pointer: | * |---->| 1 | 2 | 3 |...|
+---+ +-----------+---+
length: | 3 |
+---+
capacity: | 4 |
+---+