Как получить изменяемую структуру из HashMap?
У меня есть хэш-карта для всех моих состояний, которая является HashMap<String, Rc<State>>
и я хочу позвонить текущему участнику fn init(&mut self)
, Но я получаю сообщение об ошибке со следующим кодом:
...
if let Some(state) = self.states.get_mut(state_id) {
(*state).init();
}
...
Вот ошибка:
src/main.rs:70:25: 70:33 error: cannot borrow immutable borrowed content as mutable
src/main.rs:70 (*state).shutdown();`
в отличие от документации, проблема в том, что get_mut
возвращает изменяемую ссылку на состояние, а не ссылку на изменяемое состояние. Так как же получить ссылку на изменяемое состояние?
1 ответ
Основная идея в Rust: либо Aliasing, либо Mutable, но не оба.
Псевдоним означает наличие нескольких активных указателей на одно и то же значение.
Что такое Rc<T>
? Это совместное владение, алиасинг стоимости. таким образом Rc<T>
не позволяет изменять значение внутри.
Есть способ обойти это с Rc
, чтобы использовать внутреннюю изменчивость с типами как Cell<U>
или же RefCell<U>
,
(Если вы пишете многопоточную программу, вы бы использовали Arc
для потокового безопасного совместного владения / псевдонимов, и вы можете использовать Mutex<U>
для поточной безопасности изменчивость интерьера вместо этого.)
Rc<Cell<U>>
позволяет мутироватьU
разрешив только запись и чтение, но не указатели на внутреннийU
значение. Нет указателей, нет псевдонимов!Rc<RefCell<U>>
позволяет мутировать методом.borrow_mut()
это будет вести подсчет заимствований во время выполнения и динамически удостоверяться, что любые изменяемые заимствования являются исключительными. Нет псевдонимов, у вас есть изменчивость!
связи
- Rust Book: выбор ваших гарантий (типы ячеек)
- Оглядываясь назад, на историю Rust: представьте, что вы снова не услышали фразу "Aliasable, Mutable" (2012)