From 416d999f8090d83fc787b556125fdfbeac7a64d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=A4=E7=8B=90=E4=B8=80=E5=86=B2?= <43949039+anonymousGiga@users.noreply.github.com> Date: Wed, 17 May 2023 15:20:22 +0800 Subject: [PATCH] Update chapter_3_7_2.md --- src/chapter_3/chapter_3_7_2.md | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/chapter_3/chapter_3_7_2.md b/src/chapter_3/chapter_3_7_2.md index 75dc110..ec2c0ac 100644 --- a/src/chapter_3/chapter_3_7_2.md +++ b/src/chapter_3/chapter_3_7_2.md @@ -241,3 +241,42 @@ int main() 在执行第14行前,其内存布局为: ![注释](../../assets/11.png) + +当执行第14行后,变成如下: + +![注释](../../assets/12.png) + +第14行执行后,ptr就变成了一个悬垂指针(或者交悬垂引用),然后在第16行继续使用ptr,则会发生错误。 + +- 在 Rust 中,编译器确保引用永远不会变成悬垂状态。 + +如下代码因为会产生悬垂引用,编译将不会通过: +```Rust +fn main() { + let reference_to_nothing = dangle(); +} +fn dangle() -> &String { + let s = String::from("hello"); + &s // s在花括号前离开作用域,将会变得无效,返回的指向s的引用将是一个悬垂引用 +} +``` + +*思考:为什么下面的代码是正确的* ? +```Rust +fn main() { + let s = no_dangle(); + println!("s = {:?}", s); +} + +fn no_dangle() -> String { + let s = String::from("hello"); + s +} // 此处s虽然离开了函数这个作用域范围,但是它的所有权是被转移出去了,值并没有释放 +``` + +#### 4. 引用的规则总结 +引用的规则可以总结如下: + +- 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。 +- 引用必须总是有效的(不能是悬垂引用)。 +