2022-12-21 16:36:30 +01:00
|
|
|
# `Rc`
|
|
|
|
|
|
|
|
[`Rc`][1] is a reference-counted shared pointer. Use this when you need to refer
|
|
|
|
to the same data from multiple places:
|
|
|
|
|
|
|
|
```rust,editable
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let mut a = Rc::new(10);
|
|
|
|
let mut b = a.clone();
|
|
|
|
|
|
|
|
println!("a: {a}");
|
|
|
|
println!("b: {b}");
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-02-09 21:46:40 +00:00
|
|
|
* 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 context.
|
|
|
|
* You can *downgrade* a shared pointer into a [`Weak`][4] pointer to create cycles
|
|
|
|
that will get dropped.
|
2022-12-21 16:36:30 +01:00
|
|
|
|
|
|
|
[1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
|
|
|
|
[2]: https://doc.rust-lang.org/std/cell/index.html
|
2022-12-28 10:15:17 +01:00
|
|
|
[3]: ../concurrency/shared_state/arc.md
|
2023-02-09 21:46:40 +00:00
|
|
|
[4]: https://doc.rust-lang.org/std/rc/struct.Weak.html
|
2023-01-11 14:04:30 +01:00
|
|
|
|
|
|
|
<details>
|
|
|
|
|
|
|
|
* Like C++'s `std::shared_ptr`.
|
|
|
|
* `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.
|
2023-02-09 21:46:40 +00:00
|
|
|
* 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:#?}");
|
|
|
|
}
|
|
|
|
```
|
2023-01-11 14:04:30 +01:00
|
|
|
|
|
|
|
</details>
|