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);
2023-04-27 14:46:09 -07:00
let mut b = Rc::clone(&a);
2022-12-21 16:36:30 +01:00
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].
2023-07-18 11:03:45 +02:00
* See [`Arc` ][3] and [`Mutex` ][4] if you are in a multi-threaded context.
* You can *downgrade* a shared pointer into a [`Weak` ][5] pointer to create cycles
2023-02-09 21:46:40 +00:00
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-07-18 11:03:45 +02:00
[4]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
[5]: https://doc.rust-lang.org/std/rc/struct.Weak.html
2023-01-11 14:04:30 +01:00
< details >
2023-04-27 14:46:09 -07:00
* `Rc` 's count ensures that its contained value is valid for as long as there are references.
2023-07-06 15:03:06 +02:00
* `Rc` in Rust is like `std::shared_ptr` in C++.
2023-04-27 14:46:09 -07:00
* `Rc::clone` is cheap: it creates a pointer to the same allocation and increases the reference count. Does not make a deep clone and can generally be ignored when looking for performance issues in code.
2023-01-11 14:04:30 +01:00
* `make_mut` actually clones the inner value if necessary ("clone-on-write") and returns a mutable reference.
2023-02-26 18:05:01 -08:00
* Use `Rc::strong_count` to check the reference count.
* Compare the different datatypes mentioned. `Box` enables (im)mutable borrows that are enforced at compile time. `RefCell` enables (im)mutable borrows that are enforced at run time and will panic if it fails at runtime.
2023-04-27 14:46:09 -07:00
* `Rc::downgrade` gives you a *weakly reference-counted* object to
2023-02-09 21:46:40 +00:00
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 >