rust / intermediate
Snippet
Shared Ownership with Rc<T>
Rc<T> (Reference Counting) enables shared ownership of heap-allocated data in single-threaded contexts. Unlike Box<T> where ownership is unique, Rc<T> allows multiple parts of your code to own the same data. The strong_count() method returns how many Rc references point to the data. When the last Rc is dropped, the inner data is automatically deallocated. Rc<T> provides only shared (immutable) access; for mutable shared ownership, you would need RefCell<T> inside Rc<T>. This is useful for caches, configuration objects, or any data that needs to be accessed from multiple places without clear ownership.
snippet.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use std::rc::Rc;#[derive(Debug)]struct Config {name: String,version: String,}fn main() {let config = Rc::new(Config {name: "MyApp".to_string(),version: "1.0.0".to_string(),});println!("Original ref count: {}", Rc::strong_count(&config));{let config_clone = Rc::clone(&config);println!("After clone ref count: {}", Rc::strong_count(&config_clone));println!("Config in scope: {:?}", config_clone);}println!("After scope ref count: {}", Rc::strong_count(&config));let another_clone = Rc::clone(&config);println!("Final ref count: {}", Rc::strong_count(&another_clone));drop(another_clone);println!("After drop ref count: {}", Rc::strong_count(&config));}
Breakdown
1
use std::rc::Rc;
Import Rc for reference-counted smart pointer (single-threaded only)
2
#[derive(Debug)]
Derive Debug trait to allow printing the Config struct
3
struct Config {
Define a simple configuration struct to demonstrate shared ownership
4
let config = Rc::new(Config { ... });
Create initial Rc wrapping the Config data on the heap
5
Rc::strong_count(&config)
Get current reference count - should be 1 initially
6
let config_clone = Rc::clone(&config);
Clone creates a new Rc pointing to same data, increments ref count
7
strong_count returns 2
Now two Rc instances point to the same data
8
} // config_clone dropped here
When clone goes out of scope, ref count decrements back to 1
9
let another_clone = Rc::clone(&config);
Create yet another clone, ref count goes back to 2
10
drop(another_clone);
Explicitly drop one clone to see ref count decrease
11
strong_count is 1 again
Only original Rc remains, data will be freed when it drops