Rc

Когда необходимо множественное владение, может использоваться Rc (счётчик ссылок). Rc отслеживает количество ссылок, то есть количество владельцев значения, сохранённого внутри Rc.

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

При клонировании Rc никогда не делается глубокая копия. Клонирование лишь создаёт ещё один указатель на обёрнутое значение и увеличивает счётчик.

use std::rc::Rc;

fn main() {
    let rc_examples = "Примеры с Rc".to_string();
    {
        println!("--- Создан rc_a ---");
        
        let rc_a: Rc<String> = Rc::new(rc_examples);
        println!("Счётчик ссылок в rc_a: {}", Rc::strong_count(&rc_a));
        
        {
            println!("--- rc_a клонировано в rc_b ---");
            
            let rc_b: Rc<String> = Rc::clone(&rc_a);
            println!("Счётчик ссылок в rc_b: {}", Rc::strong_count(&rc_b));
            println!("Счётчик ссылок в rc_a: {}", Rc::strong_count(&rc_a));
            
            // Два `Rc` равны, если равны их внутренние значения
            println!("rc_a и rc_b равны: {}", rc_a.eq(&rc_b));
            
            // Мы можем напрямую использовать методы внутреннего значения
            println!("Размер значения внутри rc_a: {}", rc_a.len());
            println!("Значение rc_b: {}", rc_b);
            
            println!("--- rc_b удаляется ---");
        }
        
        println!("Счётчик ссылок в rc_a: {}", Rc::strong_count(&rc_a));
        
        println!("--- rc_a удаляется ---");
    }
    
    // Ошибка! Строка `rc_examples` уже перемещена в `rc_a`
    // И когда `rc_a` был удалён, `rc_examples` удалилась вместе с ним
    // println!("rc_examples: {}", rc_examples);
    // TODO ^ Попробуйте раскомментировать эту строку
}

Смотрите также:

std::rc and std::sync::arc.