引用
那么引用,如 &String
或 &mut String
,它们在内存中是如何表示的呢?
Rust 中的大多数引用1在内存中都是以指向内存位置的指针形式表示的。因此,它们的大小与指针的大小相同,即 usize
。
你可以使用 std::mem::size_of
来验证这一点:
#![allow(unused)] fn main() { assert_eq!(std::mem::size_of::<&String>(), 8); assert_eq!(std::mem::size_of::<&mut String>(), 8); }
特别是,一个 &String
是指向存储 String
元数据的内存位置的指针。如果你运行这段代码:
#![allow(unused)] fn main() { let s = String::from("嘿"); let r = &s; }
在内存中你会得到类似这样的布局:
--------------------------------------
| |
+----v----+--------+----------+ +----|----+
Stack | pointer | length | capacity | | pointer |
| | | 3 | 5 | | |
+----|----+--------+----------+ +---------+
| s r
|
v
+---+---+---+---+---+
Heap | H | e | y | ? | ? |
+---+---+---+---+---+
可以说,这是一个指向指向堆分配数据的指针的指针。&mut String
的情况也是如此。
并非所有指针都指向堆
上述例子澄清了一点:并非所有指针都指向堆。它们只是指向一个内存位置,这个位置_可能_在堆上,但不一定是。
参考
- 本节练习位于
exercises/03_ticket_v1/10_references_in_memory
1
在课程的后续部分中,我们将讨论胖指针,即带有附加元数据的指针。顾名思义,它们比本章讨论的指针(也称为瘦指针)更大。