第14章 内存模型
Rust 还没有明确的内存模型。许多学者和行业专业人士正在研究各种提案,但就目前而言,这在该语言中仍是一个未明确定义的地方。
内存分配和生存期
程序的程序项是那些函数、模块和类型,它们的值在编译时被计算出来,并且唯一地存储在 Rust 进程的内存映像中。程序项既不是动态分配的,也不是动态释放的。
堆是描述 box类型(译者注:box是一种堆分配形式,该堆分配返回一个指向该堆分配的内存地址的指针,后文称这个指针为 box指针或 box引用)的通用术语。堆分配的生存期取决于指向它的 box指针的生存期。由于 box指针本身可能被传入或传出栈帧,或者存储在堆中,因此堆分配可能比初始分配它们的栈帧存活的时间长。在堆分配的整个生存期内,该堆分配被保证驻留在堆中的单一位置 — 它永远不会因移动 box指针而重新分配内存地址。
变量
变量是栈帧里的一个组件,可以是具名函数参数、匿名的临时变量或具名局部变量。
局部变量(或*本地栈(stack-local)*分配)直接持有一个值,该值在栈内存中分配。该值是栈帧的一部分。
局部变量是不可变的,除非特别声明。例如:let mut x = ...。
函数参数是不可变的,除非用 mut 声明。关键字 mut 只应用于紧跟着它的那个参数。例如:|mut x, y| 和 fn f(mut x: Box<i32>, y: Box<i32>) 声明了一个可变变量 x 和一个不可变变量 y。
分配时不会初始化局部变量。此处一反常态的是在帧建立时,以未初始化状态分配整个帧值的局部变量。函数中的后续语句可以初始化局部变量,也可以不初始化局部变量。局部变量只有在通过所有可到达的控制流路径初始化后才能使用
在下面示例中,init_after_if 是在 if表达式执行后被初始化的,而 uninit_after_if 不是,因为它没有在 else 分支里被初始化。
#![allow(unused)] fn main() { fn random_bool() -> bool { true } fn initialization_example() { let init_after_if: (); let uninit_after_if: (); if random_bool() { init_after_if = (); uninit_after_if = (); } else { init_after_if = (); } init_after_if; // ok // uninit_after_if; // 错误:使用可能未初始化的 `uninit_after_if` } }