如何解决无法从匹配臂返回对成员的可变引用
作为锈借和寿命的一种练习,我想实现一个简单的二叉树。但是,我被困在某些东西上。考虑一下:
card.loading
以上内容无法通过以下方式进行编译:
struct Node {
key: i32,value: i32,left: Option<Box<Node>>,right: Option<Box<Node>>,}
struct BinaryTree {
root: Option<Box<Node>>,}
impl BinaryTree {
fn find_mut(&mut self,key: i32) -> &mut Option<Box<Node>> {
let mut node = &mut self.root;
loop {
match node {
Some(box_node) if box_node.key != key => {
node = if box_node.key < key {
&mut box_node.right
} else {
&mut box_node.left
}
},other => return other
}
}
}
}
我尝试显式设置error[E0505]: cannot move out of `node` because it is borrowed
--> src/main.rs:40:17
|
29 | fn find_mut(&mut self,key: i32) -> &mut Option<Box<Node>> {
| - let's call the lifetime of this reference `'1`
...
33 | Some(box_node) if box_node.key != key => {
| -------- borrow of `node.0` occurs here
...
40 | other => return other
| ^^^^^ ----- returning this value requires that `node.0` is borrowed for `'1`
| |
| move out of `node` occurs here
和输出的生存期。我还尝试扩展self
的手臂并匹配Some(_)
而不是None
。
(编辑2):other
的目的是将引用返回给对象,该对象应在其中创建新节点(如果找不到键)或现有节点的位置。
更详细地说明编译错误的原因是什么?我应该如何解决?我正在尝试做的甚至是一个很好的实践吗(编辑1),即将ref返回到应该进行修改的Optional(假设这不是公共方法)?
解决方法
Rust编译器发出错误的原因是因为Some(expr)
模式以其拥有的形式匹配整个表达式,即expr
已移动。
通常,通过将表达式匹配为借项Some(ref expr)
或可变借项Some(ref mut expr)
即可轻松解决,但这不是这种情况。
如果查看标准库,通常会发现as_mut()
/ as_ref()
在值不存在的情况下总是返回Option<&mut T>
而不是&mut Option<T>
。那是因为您确实要访问值,而不是像Option<Box<None>>
这样的数据结构的任何内部值。
接着,我想到了这个:
struct Node {
key: i32,value: i32,left: Option<Box<Node>>,right: Option<Box<Node>>,}
struct BinaryTree {
root: Option<Box<Node>>,}
impl BinaryTree {
fn find_mut(&mut self,key: i32) -> Option<&mut Node> {
// &mut Option<Box<Node>> -> Option<&mut Box<Node>> -> Option<&mut Node>
let mut node = self.root.as_mut().map(|boxed| boxed.as_mut());
loop {
match node {
Some(box_node) if box_node.key != key => {
node = if box_node.key < key {
box_node.right.as_mut().map(|boxed| boxed.as_mut())
} else {
box_node.left.as_mut().map(|boxed| boxed.as_mut())
}
},other => return other
}
}
}
}
也许有更好的方法来编写此代码,但目前我还不知道。
请注意,这解决了所有权问题,因为现在&mut Node
正在此处移动,并且同时使API更加美观。
关于它的良好实践,是否具有双重含义,是和否。
它可以帮助您学习如何处理借贷;另一方面,我们已经有Vec::binary_search
和BTreeMap
/ BTreeSet
,并且在crates.io
上可能还有其他实现应涵盖除最极端情况以外的所有情况自己制作搜索树毫无意义。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。