Внутренняя изменяемость в Rust
Правила заимов обычно проверяют на этапе сборки: одновременно либо много читателей, либо один писатель. Иногда снаружи нужна неизменяемая ссылка, а внутри все же хочется поменять поле. Ячейка с отложенной проверкой переносит часть правил на момент выполнения.
Метод на чтение дает общую ссылку на содержимое, метод на запись - изменяемую. Если правила нарушены, например два изменяемых заима сразу, программа останавливается. В учебном коде такие случаи лучше не воспроизводить намеренно.
Свяжем счет ссылок с ячейкой и увеличим число через изменяемый заим:
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let shared = Rc::new(RefCell::new(0));
let copy = Rc::clone(&shared);
{
let mut slot = shared.borrow_mut();
*slot += 1;
}
let read = copy.borrow();
println!("{}", *read);
}
Пока живет изменяемый заим, второй такой
же заим на ту же ячейку недоступен. После
выхода из внутреннего блока можно снова
читать через borrow.
Тот же прием помогает держать общий список имен и менять поле структуры из разных веток, если каждый раз заим берут по очереди:
use std::cell::RefCell;
use std::rc::Rc;
struct Counter {
value: i32,
}
fn main() {
let item = Rc::new(RefCell::new(Counter { value: 5 }));
let other = Rc::clone(&item);
item.borrow_mut().value = 6;
println!("{}", other.borrow().value);
}
Дано число:
let num = 1;
Положите литерал в ячейку под счетом ссылок, удвойте значение через изменяемый заим и выведите результат через чтение.
Дана структура:
struct Flag {
on: bool,
}
Создайте Flag { on: false } в
ячейке со счетом, переключите поле на
true и выведите его из второго
имени на те же данные.
Скажите, чем отличается проверка заимов у обычной ссылки и у ячейки с отложенной проверкой.