借用“匹配”臂内部的可变

Borrow mutable inside of `match` arm

提问人:Fanteria 提问时间:5/21/2023 更新时间:5/21/2023 访问量:47

问:

我是 Rust 的新手,所以如果这个问题有一个绝对明显的解决方案,我很抱歉。我找不到更简洁的方法来编写下面的代码。我知道这个代码的原因,因为已经借用了。paniccontainer

return match &container.borrow().parent {
  Some(parent) => {
    container.borrow_mut().active = false;
    Layout::move_focus(parent, direction, f)
  }
  None => Rc::clone(container),
}

问题阻止我在 ing 时更改属性。由于 ing 和更改状态在我的代码中是独立的,我认为此代码是安全的。containermatchparentmatchparentactive

我也知道这可以通过移出可变借用并更改为以下代码来解决。变量设置为开头。matchmatchif letactivetrue

{
  container.borrow_mut().active = false;
}
if let Some(parent) = &container.borrow().parent {
  return Layout::move_focus(parent, direction, f);
}
container.borrow_mut().active = true;
Rc::clone(container)

有没有一种更易读、更简洁的方法来编写具有相同功能的代码?

如果它对解决这个问题很重要,那么整个代码就会实现在内部小部件上有容器的节点,其中容器必须知道它们的父级。

函数声明:

pub fn move_focus(
  container: &Rc<RefCell<Container>>,
  direction: Direction,
  f: fn(&RcCon) -> Option<Rc<RefCell<Container>>>,
) -> Rc<RefCell<Container>>

结构:

pub struct Container {
    pub items: Vec<Item>,
    pub layout: Layout,
    pub direction: Direction,
    pub parent: Option<Rc<RefCell<Container>>,
    pub act_index: usize,
    pub active: bool,
}

pub enum Item {
    Container(RcCon),
    Widget(Holder),
}
Rust 借用检查器 refcell

评论


答:

1赞 Aleksander Krauze 5/21/2023 #1

您可以先借用整个容器,然后对它进行操作。mut

let mut c = container.borrow_mut();

return match c.parent {
  Some(parent) => {
    c.active = false;
    Layout::move_focus(parent, direction, f)
  }
  None => Rc::clone(container),
}

作为参数传递也不是惯用的锈迹。更喜欢直接传递。&RcRc

评论

0赞 Fanteria 5/21/2023
这个原因不能借用为可变的,因为以后使用 immutable。将输出添加到变量并返回变量解决了这个问题。cc.active = falsemove_focusmove_focus