英文:
Borrow mutable inside of `match` arm
问题
I'm new to Rust, so I'm sorry if this question has an absolutely obvious solution. I cannot find cleaner way to write the code below. I know this code cause panic
because of container
is already borrowed.
问题是在匹配 parent
时,阻止我更改 container
属性。由于匹配 parent
并更改 active
状态,这两者在我的代码中是独立的,所以我认为这段代码是安全的。
我也知道可以通过将可变引用移出 match
并将 match
更改为 if let
来解决这个问题,如下所示。变量 active
在开始时设置为 true
。
是否有更可读更清晰的方式来编写具有相同功能的代码?
如果解决这个问题很重要,整个代码实现了具有容器内部小部件的节点,其中容器必须知道其父级。
函数声明:
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),
}
英文:
I'm new to Rust, so I'm sorry if this question has an absolutely obvious solution. I cannot find cleaner way to write the code below. I know this code cause panic
because of container
is already borrowed.
return match &container.borrow().parent {
Some(parent) => {
container.borrow_mut().active = false;
Layout::move_focus(parent, direction, f)
}
None => Rc::clone(container),
}
Problem there is preventing me from changing a container
attributes while I'm match
ing parent
. Because of match
ing parent
and changing active
state, that are independent in my code, I think this code is safe.
I also know this can be solved by moving mutable borrow out of match
and changing match
to if let
as is shown in the code below. Variable active
is set to true
at the beginning.
{
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)
Is there a more readable and cleaner way to write code with the same functionality?
If it is important for solving this problem the whole code implements nodes that have containers on widgets inside, where containers must know their parents.
Function declaration:
pub fn move_focus(
container: &Rc<RefCell<Container>>,
direction: Direction,
f: fn(&RcCon) -> Option<Rc<RefCell<Container>>>,
) -> Rc<RefCell<Container>>
Structs:
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),
}
答案1
得分: 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),
}
另外,将 &Rc
作为参数传递不符合 Rust 的惯用方式。建议直接传递 Rc
。
英文:
You can borrow whole container as mut
firstly, and then do operations on it.
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),
}
Also passing &Rc
as an argument is not idiomatic rust. Prefer passing Rc
directly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论