|
|
|
@ -56,7 +56,7 @@ Rust 的内存安全性保证使其难以意外地制造永远也不会被清理
|
|
|
|
|
|
|
|
|
|
### 避免引用循环:将 `Rc<T>` 变为 `Weak<T>`
|
|
|
|
|
|
|
|
|
|
到目前为止,我们已经展示了调用 `Rc::clone` 会增加 `Rc<T>` 实例的 `strong_count`,和只在其 `strong_count` 为 0 时才会被清理的 `Rc<T>` 实例。你也可以通过调用 `Rc::downgrade` 并传递 `Rc<T>` 实例的引用来创建其值的 **弱引用**(_weak reference_)。强引用代表如何共享 `Rc<T>` 实例的所有权。弱引用并不属于所有权关系,当 `Rc<T>` 实例被清理时其计数没有影响。他们不会造成引用循环,因为任何弱引用的循环会在其相关的强引用计数为 0 时被打断。
|
|
|
|
|
到目前为止,我们已经展示了调用 `Rc::clone` 会增加 `Rc<T>` 实例的 `strong_count`,和只在其 `strong_count` 为 0 时才会被清理的 `Rc<T>` 实例。你也可以通过调用 `Rc::downgrade` 并传递 `Rc<T>` 实例的引用来创建其值的 **弱引用**(_weak reference_)。强引用代表如何共享 `Rc<T>` 实例的所有权。弱引用并不属于所有权关系,当 `Rc<T>` 实例被清理时其计数没有影响。他们不会造成引用循环,因为任何涉及弱引用的循环会在其相关的值的强引用计数为 0 时被打断。
|
|
|
|
|
|
|
|
|
|
调用 `Rc::downgrade` 时会得到 `Weak<T>` 类型的智能指针。不同于将 `Rc<T>` 实例的 `strong_count` 加 1,调用 `Rc::downgrade` 会将 `weak_count` 加 1。`Rc<T>` 类型使用 `weak_count` 来记录其存在多少个 `Weak<T>` 引用,类似于 `strong_count`。其区别在于 `weak_count` 无需计数为 0 就能使 `Rc<T>` 实例被清理。
|
|
|
|
|
|
|
|
|
@ -76,7 +76,7 @@ Rust 的内存安全性保证使其难以意外地制造永远也不会被清理
|
|
|
|
|
{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-27/src/main.rs:here}}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
我们希望能够 `Node` 拥有其子节点,同时也希望通过变量来共享所有权,以便可以直接访问树中的每一个 `Node`,为此 `Vec<T>` 的项的类型被定义为 `Rc<Node>`。我们还希望能修改其他节点的子节点,所以 `children` 中 `Vec<Rc<Node>>` 被放进了 `RefCell<T>`。
|
|
|
|
|
我们希望能够 `Node` 拥有其子节点,同时也希望能将所有权共享给变量,以便可以直接访问树中的每一个 `Node`,为此 `Vec<T>` 的项的类型被定义为 `Rc<Node>`。我们还希望能修改其他节点的子节点,所以 `children` 中 `Vec<Rc<Node>>` 被放进了 `RefCell<T>`。
|
|
|
|
|
|
|
|
|
|
接下来,使用此结构体定义来创建一个叫做 `leaf` 的带有值 3 且没有子节点的 `Node` 实例,和另一个带有值 5 并以 `leaf` 作为子节点的实例 `branch`,如示例 15-27 所示:
|
|
|
|
|
|
|
|
|
|