【问题标题】:How to get mutable struct from HashMap?如何从 HashMap 获取可变结构?
【发布时间】:2015-08-03 14:50:55
【问题描述】:

我的所有州都有一个哈希图,即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 返回一个对状态的可变引用,而不是对可变状态的引用。那么如何获得对可变状态的引用呢?

【问题讨论】:

  • if let Some(mut state) = self.states.get_mut(state_id) { 有帮助吗?
  • 不,已经试过了。哦,我使用RefCells 让它工作了,但我宁愿不使用它们,因为它们速度较慢,如果我不非常小心,很容易恐慌。
  • 那么您似乎想要内部可变性。 Playpen example
  • 如果你不使用 Rc 是可能的,但即使 the Rc documentation 使用 RefCells 来实现内部可变性。
  • 是的,这与HashMap 无关。 Rust 无法推断 Rc 内部值的可变性,因此只要 Rc 不是唯一的,它就禁止突变。如果只有一个引用,您可以使用 get_mut。但是,您不妨将Rc 全部删除

标签: rust borrow-checker


【解决方案1】:

Rust 的一个基本理念是:别名或可变性,但不能两者兼而有之。

别名意味着拥有多个指向同一个值的活动指针。

Rc<T> 是什么?它是共享所有权,别名化一个值。因此Rc<T> 不允许改变里面的值。

Rc 有一种解决方法,可以将 interior mutabilityCell<U>RefCell<U> 等类型一起使用。

(如果你编写一个多线程程序,你可以使用Arc 来实现线程安全的共享所有权/别名,你可以使用Mutex<U> 来实现线程安全的内部可变性。)

  • Rc<Cell<U>> 允许通过只允许写入和读出来改变 U,但不允许指向内部 U 值的指针。没有指针,没有别名!

  • Rc<RefCell<U>> 允许通过 .borrow_mut() 方法进行变异,该方法将在运行时保持借用计数,并动态确保任何可变借用都是独占的。没有别名,你有可变性!

链接

【讨论】:

    猜你喜欢
    • 2012-02-21
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 2020-11-17
    • 1970-01-01
    • 2020-01-08
    相关资源
    最近更新 更多