Rc in Rust
Reference counting is a smart pointer mechanism that gives you a reference-counted value. It keeps a count of all owners and drops the value only when the counter reaches 0.
The count increases by 1 each time the pointer is cloned. Unlike deep cloning, this does not create a new value on the heap; instead, it increments the counter next to the value. Each time a clone is dropped, the counter is decremented; if the counter reaches 0, the actual value is dropped.
Standard reference counting gives a read-only reference by default and is not thread-safe if the counter increments and decrements are non-atomic.
std::rc::Rc is a smart pointer that gives you a reference-counted value. It keeps a count of all owners and drops the value only when the counter reaches 0. The count goes up by one each time the pointer is cloned with Rc::clone(&rc).
Unlike Box::new().clone(), these do not create a new value on the heap; instead, it just increments the counter next to the value. Each time a clone is dropped, the counter is decremented; if the counter reaches 0, the actual value is dropped.
Note: Rc gives a read-only reference; to get a mutable reference, you can either use interior mutability or Rc::get_mut or Rc::make_mut to get a mutable reference. It only works with a single reference; to get the number of references an Rc has, use Rc::strong_count.
use std::rc::Rc;
fn main() {
let mut num = Rc::new(5);
if let Some(val) = Rc::get_mut(&mut num) {
*val = 42;
}
println!("{num:?}"); // 42
}
It's a zero-cost abstraction way of taking a mutable reference from an Rc.
Rc can't be sent across threads because it's not thread-safe and doesn't implement Send and Sync, because if two threads try to update the count at once, it will result in inconsistent behaviour.
