CodeBlanks Logo Icon CodeBlanks

Rc<T>

Learn shared ownership with Rc<T>.

Rc<T>

Sometimes a value needs several owners: for example, many edges share a graph node. Rc<T> (reference counted) keeps the number of owners; when the last owner is dropped, the value is dropped too:

use std::rc::Rc;

let a = Rc::new(String::from("paylaşılan"));
let b = Rc::clone(&a);           // not a deep copy, counter +1
println!("{}", Rc::strong_count(&a));   // 2

Rc::clone only increments the counter, it doesn't copy the data. a.clone() does the same, but writing Rc::clone(&a) shows clearly that it's a cheap operation.

Counter and scope

Each time an Rc copy goes out of scope, the counter goes down:

let a = Rc::new(5);
{
    let _c = Rc::clone(&a);
    println!("{}", Rc::strong_count(&a));   // 2
}
println!("{}", Rc::strong_count(&a));       // 1

Rc is single-threaded; since its counter isn't atomic it can't be sent to another thread (it isn't Send). Sharing across threads needs Arc.

Practice Shared text

Create Rc::new(String::from("paylaşılan")) and take a copy. In an inner block take one more copy and print the counter; after the block print the counter and the text separated by a space.

Starter code

main.rs
use std::rc::Rc;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::rc::Rc;

fn main() {
    let a = Rc::new(String::from("paylaşılan"));
    let _b = Rc::clone(&a);
    {
        let _c = Rc::clone(&a);
        println!("{}", Rc::strong_count(&a));
    }
    println!("{} {}", Rc::strong_count(&a), a);
}

Expected output

3
2 paylaşılan

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Can the value inside an <code>Rc&lt;T&gt;</code> be changed?

  • Not directly; Rc only gives shared (&T) access Correct answer
  • Yes, every owner can change it
  • Only the first owner
  • Yes, with mut Rc

Explanation: If several owners changed it at once, the borrowing rules would break. Use Rc<RefCell<T>> to change it.

2 Share ownership

Question
let a = Rc::new(String::from("x"));
let b = Rc::____(&a);
Answer
let a = Rc::new(String::from("x"));
let b = Rc::clone(&a);

Explanation: Rc::clone increments the counter and gives a new owner of the same data.

3 Operation and counter

Term Meaning
Rc::new(x) 1
+ Rc::clone(&a) 2
+ one more copy 3
When all are dropped Value is freed

All lessons in Intermediate