引用

那么引用,如 &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

在课程的后续部分中,我们将讨论胖指针,即带有附加元数据的指针。顾名思义,它们比本章讨论的指针(也称为瘦指针)更大。