From db7765cab0ae3afc3c6493cc3d346c2126b18448 Mon Sep 17 00:00:00 2001 From: Unisko PENG Date: Tue, 9 May 2023 11:26:09 +0800 Subject: [PATCH] Update Ch15 --- projects/box_demo/src/main.rs | 26 ++++++++++++++++++++++++-- src/Ch15_Smart_Pointers.md | 7 +++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/projects/box_demo/src/main.rs b/projects/box_demo/src/main.rs index e7a11a9..7d9d340 100644 --- a/projects/box_demo/src/main.rs +++ b/projects/box_demo/src/main.rs @@ -1,3 +1,25 @@ -fn main() { - println!("Hello, world!"); +use std::ops::Deref; + +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} + +impl Deref for MyBox { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn main() { + let boxed_string = MyBox::new(String::from("装箱的字符串")); + + let x = 5; + let y = &x; + println! ("{}, {}", *boxed_string, *y); } diff --git a/src/Ch15_Smart_Pointers.md b/src/Ch15_Smart_Pointers.md index d43141b..2f5c06d 100644 --- a/src/Ch15_Smart_Pointers.md +++ b/src/Ch15_Smart_Pointers.md @@ -451,13 +451,16 @@ fn main() { *清单 15-13:如果 Rust 没有解引用强制转换,我们将不得不编写的代码* -其中的 `(*m)` 将那个 `MyBox` 解引用为了一个 `String`。随后的 `&` 与 `[..]`,则取了与 `hello` 函数签名相匹配,等于整个字符串的该 `String` 的字符串切片。这种不带有解引用强制转换的代码,因为涉及到全部的这些符号,而更难于阅读、编写与理解。正是解引用强制转换,实现了 Rust 为咱们自动处理这些转换。 +`(*m)` 将 `MyBox` 解引用为 `String`。然后 `&` 和 `[..]` 获取 `String` 等于整个字符串的一个字符串切片,以匹配 `hello` 的签名。由于涉及所有这些符号,这段没有解引用强制转换的代码更难阅读、编写和理解。 解引用强制转换允许 Rust 自动为我们处理这些转换。 -在为这些涉及到的类型定义了 `Deref` 特质时,Rust 将分析这些类型,并运用必要次数的 `Deref::deref`,来获取到与函数或方法定义中参数类型相匹配的一个引用。所需插入的 `Deref::deref` 次数,是在编译时解算出来的,因此解引用强制转换优势的利用,并无运行时的代价。 +在所涉及的类型定义了 `Deref` 特质时,Rust 将分析这些类型,并根据需要多次使用 `Deref::deref`,来获得与参数类型匹配的引用。所需插入 `Deref::deref` 次数,是在编译时就已确定,所以利用解引用强制转换的优势,没有运行时的代价! ### 解引用强制转换与可变性的互动方式 +**How Deref Coercion Interacts with Mutability** + + 与使用 `Deref` 特质来覆写不可变引用上的 `*` 运算符的方式类似,咱们可以使用 `DerefMut` 特质,来覆写可变引用上的 `*` 运算符。 在以下三种情形下,Rust 会在他发现类型与特质的实现时,执行强制引用转换: