Rc<T>, умный указатель с подсчётом ссылок

бывают случаи, когда у одного значения может быть несколько владельцев. Например, в Графовых структурах может быть несколько рёбер, указывающих на один и тот же узел.

Warning

тип Rust Rc<T> — позволяет явно включить множественное владение. Тип Rc<T> отслеживает количество ссылок на значение, чтобы определить, используется ли оно ещё. Если ссылок на значение нет, значение может быть очищено и при этом ни одна ссылка не станет недействительной.

Note

Тип Rc<T> используется, когда мы хотим разместить в куче некоторые данные для чтения несколькими частями нашей программы и не можем определить во время компиляции, какая из частей завершит использование данных последней.

Warning

Rc<T> используется только в однопоточных сценариях.

Не рабочий пример

RUST это просто не допустит

list

b и c совместно владеют хвостом a = 5 и 10

enum List {
    Cons(i32, Box<List>),
    Nil,
}

use crate::List::{Cons, Nil};

fn main() {
    let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
    let b = Cons(3, Box::new(a));
    let c = Cons(4, Box::new(a));
}

Решение через Rc

enum List {
    Cons(i32, Rc<List>),
    Nil,
}

use crate::List::{Cons, Nil};
use std::rc::Rc;

fn main() {
    let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
    let b = Cons(3, Rc::clone(&a));
    let c = Cons(4, Rc::clone(&a));
}
  1. a, b, c объявляются как Rc
  2. в b клонируется a Rc::clone
  3. в c клонируется a Rc::CLOSE

Вызов Rc::clone только увеличивает счётчик ссылок,

Rc::strong_count — подсчитывает количество ссылок

#![allow(unused)]
fn main() {
    println!("count after creating b = {}", Rc::strong_count(&a));

}

С помощью неизменяемых ссылок, тип Rc позволяет обмениваться данными между несколькими частями вашей программы только для чтения данных.