Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.