Update ch15-02-deref.md

pull/266/head
CAi 6 years ago committed by GitHub
parent 2dc79727dd
commit 4e394fe608
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -79,7 +79,7 @@ not satisfied
### 像引用一样使用 `Box<T>` ### 像引用一样使用 `Box<T>`
可以重写示例 15-8 中的代码来使用 `Box<T>` 而不是引用,同时借引用运算符也一样能工作,如示例 15-9 所示: 可以重写示例 15-8 中的代码,使用 `Box<T>` 来代替引用,解引用运算符也一样能工作,如示例 15-9 所示:
<span class="filename">文件名: src/main.rs</span> <span class="filename">文件名: src/main.rs</span>
@ -177,7 +177,7 @@ this is what you have to specify in order to implement it. /Carol -->
`deref` 方法体中写入了 `&self.0`,这样 `deref` 返回了我希望通过 `*` 运算符访问的值的引用。示例 15-11 中的 `main` 函数中对 `MyBox<T>` 值的 `*` 调用现在可以编译并能通过断言了! `deref` 方法体中写入了 `&self.0`,这样 `deref` 返回了我希望通过 `*` 运算符访问的值的引用。示例 15-11 中的 `main` 函数中对 `MyBox<T>` 值的 `*` 调用现在可以编译并能通过断言了!
没有 `Deref` trait 的话,编译器只能解引用 `&` 引用。`Deref` trait 的 `deref` 方法为编译器提供了获取任何实现了 `Deref` 的类型值的能力,为了获取其知道如何解引用的 `&` 引用编译器可以调用 `deref` 方法 没有 `Deref` trait 的话,编译器可以解引用的只有 `&` 引用类型;有了 `Deref` trait 之后,对任何实现 `Deref` trait 的类型,编译器都能(通过解引用的形式)从其获取一个值。只要调用这个类型的 `deref` 方法,编译器就可以得到一个 `&` 引用,再对 `&` 引用进行解引用对它来说就是熟悉的操作了
当我们在示例 15-11 中输入 `*y`Rust 事实上在底层运行了如下代码: 当我们在示例 15-11 中输入 `*y`Rust 事实上在底层运行了如下代码:
@ -189,11 +189,11 @@ this is what you have to specify in order to implement it. /Carol -->
up front? --> up front? -->
<!-- we've tried to clarify below /Carol --> <!-- we've tried to clarify below /Carol -->
Rust 将 `*` 运算符替换为 `deref` 方法调用和一个普通解引用,如此我们便无需担心是否需要调用 `deref` 方法。Rust 的这个功能让我们可以编写同时处理常规引用或实现了 `Deref` 的类型的代码 Rust 将 `*` 运算符替换为先调用 `deref` 方法再进行直接引用的操作,如此我们便不用担心是不是还需要手动调用 `deref` 方法了。Rust 的这个特性可以让我们写出行为一致的代码,无论是面对的是常规引用还是实现了 `Deref` 的类型
`deref` 方法返回值的引用,以及 `*(y.deref())` 括号外边的普通解引用仍为必须的原因在于所有权。如果 `deref` 方法直接返回值而不是值的引用,其值(的所有权)将被移出 `self`。在这里以及大部分使用解引用运算符的情况下我们并不希望获取 `MyBox<T>` 内部值的所有权。 `deref` 方法返回值的引用,以及 `*(y.deref())` 括号外边的普通解引用仍为必须的原因在于所有权。如果 `deref` 方法直接返回值而不是值的引用,其值(的所有权)将被移出 `self`。在这里以及大部分使用解引用运算符的情况下我们并不希望获取 `MyBox<T>` 内部值的所有权。
注意`*` 替换为 `deref` 调用和 `*` 调用的过程在每次使用 `*` 的时候都会发生一次。`*` 的替换并不会无限递归进行。最终的数据类型是 `i32`,它与示例 15-11 中 `assert_eq!``5` 相匹配。 注意,每次当我们在代码中使用 `*` 时, `*` 运算符都被替换成了先调用 `deref` 方法再接着使用 `*` 解引用的操作,且只会发生一次,不会对 `*` 操作符无限递归替换,解引用出上面 `i32` 类型的值就停止了,这个值与示例 15-11 中 `assert_eq!``5` 相匹配。
### 函数和方法的隐式解引用强制多态 ### 函数和方法的隐式解引用强制多态
@ -204,7 +204,7 @@ not, can you change this to an active tone? -->
<!-- Yes, it is something that happens behind the scenes, which is why we <!-- Yes, it is something that happens behind the scenes, which is why we
describe it as implicit. /Carol --> describe it as implicit. /Carol -->
**解引用强制多态***deref coercions*)是 Rust 出于方便的考虑作用于函数或方法的参数的。其将实现了 `Deref` 的类型的引用转换为 `Deref` 所能够将原始类型转换的类型的引用。解引用强制多态发生于当作为参数传递给函数或方法的特定类型的引用不同于函数或方法签名中定义参数类型的时候,这时会有一系列的 `deref` 方法调用会将提供的类型转换为参数所需的类型。 **解引用强制多态***deref coercions*)是 Rust 表现在函数或方法传参上的一种便利。其将实现了 `Deref` 的类型的引用转换为原始类型通过 `Deref` 所能够转换的类型的引用。当这种特定类型的引用作为实参传递给和形参类型不同的函数或方法时,解引用强制多态将自动发生。这时会有一系列的 `deref` 方法被调用,把我们提供的类型转换成了参数所需的类型。
解引用强制多态的加入使得 Rust 程序员编写函数和方法调用时无需增加过多显式使用 `&``*` 的引用和解引用。这个功能也使得我们可以编写更多同时作用于引用或智能指针的代码。 解引用强制多态的加入使得 Rust 程序员编写函数和方法调用时无需增加过多显式使用 `&``*` 的引用和解引用。这个功能也使得我们可以编写更多同时作用于引用或智能指针的代码。

Loading…
Cancel
Save