修改 ch15-02-deref.md (#74)

Co-authored-by: YangQi <2419731931@qq.com>
This commit is contained in:
itfanr 2022-05-27 14:33:57 +08:00 committed by GitHub
parent f09f81aa79
commit 0666a11beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -137,7 +137,7 @@ impl<T> Deref for MyBox<T> {
`deref` 方法体中写入了 `&self.0`,这样 `deref` 返回了我希望通过 `*` 运算符访问的值的引用。示例 15-9 中的 `main` 函数中对 `MyBox<T>` 值的 `*` 调用现在可以编译并能通过断言了!
没有 `Deref` trait 的话,编译器只会解引用 `&` 引用类型。`deref` 方法向编译器提供了获取任何实现了 `Deref` trait 的类型的值,并且调用这个类型的 `deref` 方法来获取一个它知道如何解引用的 `&` 引用的能力
没有 `Deref` trait 的话,编译器只会`&` 引用类型解引用。`deref` 方法向编译器提供了一种能力:能够获取任何实现了 `Deref` trait 的类型的值,并且可以通过调用这个类型的 `deref` 方法来获取一个解引用方法已知`&` 引用。
当我们在示例 15-9 中输入 `*y`Rust 事实上在底层运行了如下代码:
@ -262,12 +262,12 @@ fn main() {
类似于使用 `Deref` trait 重载不可变引用的 `*` 运算符Rust 提供了 `DerefMut` trait 用于重载可变引用的 `*` 运算符。
Rust 在发现类型和 trait 实现满足三种情况时会进行解引用强制转换:
Rust 在发现类型和 trait 实现满足以下三种情况时会进行解引用强制转换:
- 当 `T: Deref<Target=U>` `&T``&U`
- 当 `T: DerefMut<Target=U>` `&mut T``&mut U`
- 当 `T: Deref<Target=U>` `&mut T``&U`
- 当 `T: Deref<Target=U>` `&T``&U`
- 当 `T: DerefMut<Target=U>` `&mut T``&mut U`
- 当 `T: Deref<Target=U>` `&mut T``&U`
头两个情况除了可变性之外是相同的:第一种情况表明如果有一个 `&T`,而 `T` 实现了返回 `U` 类型的 `Deref`,则可以直接得到 `&U`。第二种情况表明对于可变引用也有着相同的行为。
前两种情况除了可变性之外是相同的:第一种情况表明如果有一个 `&T`,而 `T` 实现了返回 `U` 类型的 `Deref`,则可以直接得到 `&U`。第二种情况表明对于可变引用也有着相同的行为。
第三个情况有些微妙Rust 也会将可变引用强转为不可变引用。但是反之是 **不可能** 的:不可变引用永远也不能强转为可变引用。因为根据借用规则如果有一个可变引用其必须是这些数据的唯一引用否则程序将无法编译。将一个可变引用转换为不可变引用永远也不会打破借用规则。将不可变引用转换为可变引用则需要数据只能有一个不可变引用而借用规则无法保证这一点。因此Rust 无法假设将不可变引用转换为可变引用是可能的。
第三种情况有些微妙Rust 也会将可变引用强转为不可变引用,但是反之是 **不可能** 的,因为不可变引用永远也不能强转为可变引用。因为根据借用规则如果有一个可变引用其必须是这些数据的唯一引用否则程序将无法编译。将一个可变引用转换为不可变引用永远也不会打破借用规则。将不可变引用转换为可变引用则需要数据只能有一个不可变引用而借用规则无法保证这一点。因此Rust 无法假设将不可变引用转换为可变引用是可能的。