1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-06-15 05:40:30 +02:00

Mention rc::Weak and add an example with a cycle in the speaker notes. (#375)

This commit is contained in:
gendx
2023-02-09 21:46:40 +00:00
committed by GitHub
parent f9f04651ce
commit fbb12161eb

View File

@ -15,18 +15,52 @@ fn main() {
} }
``` ```
If you need to mutate the data inside an `Rc`, you will need to wrap the data in * If you need to mutate the data inside an `Rc`, you will need to wrap the data in
a type such as [`Cell` or `RefCell`][2]. See [`Arc`][3] if you are in a multi-threaded a type such as [`Cell` or `RefCell`][2].
context. * See [`Arc`][3] if you are in a multi-threaded context.
* You can *downgrade* a shared pointer into a [`Weak`][4] pointer to create cycles
that will get dropped.
[1]: https://doc.rust-lang.org/std/rc/struct.Rc.html [1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
[2]: https://doc.rust-lang.org/std/cell/index.html [2]: https://doc.rust-lang.org/std/cell/index.html
[3]: ../concurrency/shared_state/arc.md [3]: ../concurrency/shared_state/arc.md
[4]: https://doc.rust-lang.org/std/rc/struct.Weak.html
<details> <details>
* Like C++'s `std::shared_ptr`. * Like C++'s `std::shared_ptr`.
* `clone` is cheap: creates a pointer to the same allocation and increases the reference count. * `clone` is cheap: creates a pointer to the same allocation and increases the reference count.
* `make_mut` actually clones the inner value if necessary ("clone-on-write") and returns a mutable reference. * `make_mut` actually clones the inner value if necessary ("clone-on-write") and returns a mutable reference.
* You can `downgrade()` a `Rc` into a *weakly reference-counted* object to
create cycles that will be dropped properly (likely in combination with
`RefCell`).
```rust,editable
use std::rc::{Rc, Weak};
use std::cell::RefCell;
#[derive(Debug)]
struct Node {
value: i64,
parent: Option<Weak<RefCell<Node>>>,
children: Vec<Rc<RefCell<Node>>>,
}
fn main() {
let mut root = Rc::new(RefCell::new(Node {
value: 42,
parent: None,
children: vec![],
}));
let child = Rc::new(RefCell::new(Node {
value: 43,
children: vec![],
parent: Some(Rc::downgrade(&root))
}));
root.borrow_mut().children.push(child);
println!("graph: {root:#?}");
}
```
</details> </details>