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

RefCell

RefCell позволяет обращаться к оборачиваемому значению и изменять его, предоставляя альтернативные типы Ref и RefMut, которые имитируют &T/&mut T, но при этом не являются ссылками Rust.

Эти типы выполняют динамические проверки с помощью счётчика в RefCell, чтобы не допустить существования RefMut одновременно с другим Ref/RefMut.

Реализуя Deref (а для RefMut — DerefMut), эти типы позволяют вызывать методы внутреннего значения, не допуская утечки ссылок наружу.

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::cell::RefCell;

fn main() {
    // Обратите внимание, что `cell` НЕ объявлена как изменяемая.
    let cell = RefCell::new(5);

    {
        let mut cell_ref = cell.borrow_mut();
        *cell_ref = 123;

        // Это вызывает ошибку во время выполнения.
        // let other = cell.borrow();
        // println!("{}", other);
    }

    println!("{cell:?}");
}
  • RefCell обеспечивает обычные правила заимствования Rust (либо несколько разделяемых ссылок, либо одну эксклюзивную) с помощью проверки во время выполнения. В данном случае все заимствования очень короткие и никогда не пересекаются, поэтому проверки всегда проходят.

  • Дополнительный блок в примере нужен, чтобы завершить заимствование, созданное вызовом borrow_mut, до того как выводится ячейка. Попытка вывести заимствованный RefCell покажет только сообщение "{borrowed}".

Для дальнейшего изучения

Есть также OnceCell и OnceLock, которые позволяют инициализацию при первом использовании. Чтобы использовать их с пользой, нужно больше знаний, чем у студентов на этом этапе.