mirror of
https://github.com/KaiserY/trpl-zh-cn
synced 2024-11-09 08:51:18 +08:00
将 "泄露" 改为 "泄漏"
This commit is contained in:
parent
395381c2b4
commit
f5c03aa58d
@ -4,8 +4,8 @@
|
||||
> commit 57adb83f69a69e20862d9e107b2a8bab95169b4c
|
||||
|
||||
对于智能指针模式来说第二个重要的 trait 是 `Drop`,其允许我们在值要离开作用域时执行一些代码。可以为任何类型提供 `Drop` trait 的实现,同时所指定的代码被用于释放类似于文件或网络连接的资源。我们在智能指针上下文中讨论 `Drop` 是因为其功能几乎总是用于实现智能指针。例如,`Box<T>` 自定义了 `Drop` 用来释放 box 所指向的堆空间。
|
||||
|
||||
在其他一些语言中,我们不得不记住在每次使用完智能指针实例后调用清理内存或资源的代码。如果忘记的话,运行代码的系统可能会因为负荷过重而崩溃。在 Rust 中,可以指定每当值离开作用域时被执行的代码,编译器会自动插入这些代码。于是我们就不需要在程序中到处编写在实例结束时清理这些变量的代码 —— 而且还不会泄露资源。
|
||||
不得不记住在每次使用完智能指针实例后调用清理内存或资源的代码。如果忘记的话,运行代码的系统可能会因为负荷过重而崩溃。在 Rust 中,可以指定每当值离开作用域时被执行的代码,编译器会自动插入这些代码。于是我们就不需要在程序中到处编写在实例结束时清理这些变量的代码 —— 而且还不会泄漏资源。
|
||||
在其他一些语言中,我们
|
||||
|
||||
指定在值离开作用域时应该执行的代码的方式是实现 `Drop` trait。`Drop` trait 要求实现一个叫做 `drop` 的方法,它获取一个 `self` 的可变引用。为了能够看出 Rust 何时调用 `drop`,让我们暂时使用 `println!` 语句实现 `drop`。
|
||||
|
||||
|
@ -324,17 +324,17 @@ fn main() {
|
||||
|
||||
一旦创建了 `leaf`,其 `Rc<Node>` 的强引用计数为 1,弱引用计数为 0。在内部作用域中创建了 `branch` 并与 `leaf` 相关联,此时 `branch` 中 `Rc<Node>` 的强引用计数为 1,弱引用计数为 1(因为 `leaf.parent` 通过 `Weak<Node>` 指向 `branch`)。这里 `leaf` 的强引用计数为 2,因为现在 `branch` 的 `branch.children` 中储存了 `leaf` 的 `Rc<Node>` 的拷贝,不过弱引用计数仍然为 0。
|
||||
|
||||
当内部作用域结束时,`branch` 离开作用域,`Rc<Node>` 的强引用计数减少为 0,所以其 `Node` 被丢弃。来自 `leaf.parent` 的弱引用计数 1 与 `Node` 是否被丢弃无关,所以并没有产生任何内存泄露!
|
||||
当内部作用域结束时,`branch` 离开作用域,`Rc<Node>` 的强引用计数减少为 0,所以其 `Node` 被丢弃。来自 `leaf.parent` 的弱引用计数 1 与 `Node` 是否被丢弃无关,所以并没有产生任何内存泄漏!
|
||||
|
||||
如果在内部作用域结束后尝试访问 `leaf` 的父节点,会再次得到 `None`。在程序的结尾,`leaf` 中 `Rc<Node>` 的强引用计数为 1,弱引用计数为 0,因为现在 `leaf` 又是 `Rc<Node>` 唯一的引用了。
|
||||
|
||||
所有这些管理计数和值的逻辑都内建于 `Rc<T>` 和 `Weak<T>` 以及它们的 `Drop` trait 实现中。通过在 `Node` 定义中指定从子节点到父节点的关系为一个`Weak<T>`引用,就能够拥有父节点和子节点之间的双向引用而不会造成引用循环和内存泄露。
|
||||
所有这些管理计数和值的逻辑都内建于 `Rc<T>` 和 `Weak<T>` 以及它们的 `Drop` trait 实现中。通过在 `Node` 定义中指定从子节点到父节点的关系为一个`Weak<T>`引用,就能够拥有父节点和子节点之间的双向引用而不会造成引用循环和内存泄漏。
|
||||
|
||||
## 总结
|
||||
|
||||
这一章涵盖了如何使用智能指针来做出不同于 Rust 常规引用默认所提供的保证与取舍。`Box<T>` 有一个已知的大小并指向分配在堆上的数据。`Rc<T>` 记录了堆上数据的引用数量以便可以拥有多个所有者。`RefCell<T>` 和其内部可变性提供了一个可以用于当需要不可变类型但是需要改变其内部值能力的类型,并在运行时而不是编译时检查借用规则。
|
||||
|
||||
我们还介绍了提供了很多智能指针功能的 trait `Deref` 和 `Drop`。同时探索了会造成内存泄露的引用循环,以及如何使用 `Weak<T>` 来避免它们。
|
||||
我们还介绍了提供了很多智能指针功能的 trait `Deref` 和 `Drop`。同时探索了会造成内存泄漏的引用循环,以及如何使用 `Weak<T>` 来避免它们。
|
||||
|
||||
如果本章内容引起了你的兴趣并希望现在就实现你自己的智能指针的话,请阅读 [“The Rustonomicon”][nomicon] 来获取更多有用的信息。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user