让我们考虑一下我的存储结构,其中包含 u16 中的键向量:
pub struct Node {
pub keys: RefCell<Vec<u16>>,
pub children: RefCell<Vec<Node>>,
}
在递归过程中的某个时刻,当调用迭代子级的子级并搜索提供的密钥时,
pub fn search(&'a self, key: u16, current: Ref<'a, Node>) -> (usize, Ref<'a, Node>) {
{
let keys = current.keys.borrow();
for index in 0..keys.len() {
if keys[index] == key && current.is_leaf() {
return (index, current);
}
}
}
递归以return语句结束。该函数调用预计会返回匹配键的索引和当前 Node 实例,以便调用者可以进行一些修改。但是,rustc 对此有所抱怨:
error[E0505]: cannot move out of `current` because it is borrowed
--> src/index/btree.rs:87:36
|
84 | let keys = current.keys.borrow();
| ------- borrow of `current` occurs here
...
87 | return (index, current);
| ^^^^^^^ move out of `current` occurs here
...
90 | }
| - borrow might be used here, when `keys` is dropped and runs the destructor for type `Ref<'_, Vec<u16>>`
我知道该函数在第 84 行借用了键,只要“键”引用存在,即直到它们在方法调用后被删除,但我的问题是在算法中处理此问题的惯用方法是什么?特别是不克隆对象,这对我来说听起来像是一种解决方法?
我认为你的例子中一定遗漏了一些重要的东西。它不能按原样编译。
更改它以解决最明显的问题,并从通过
Ref<'a, Node>
切换到仅通过 &Node
,然后它会为我编译:
use std::cell::RefCell;
pub struct Node {
pub keys: RefCell<Vec<u16>>,
pub children: RefCell<Vec<Node>>,
}
impl Node {
fn is_leaf(&self) -> bool {
todo!()
}
}
pub fn search(key: u16, current: &Node) -> Option<(usize, &Node)> {
let keys = current.keys.borrow();
for index in 0..keys.len() {
if keys[index] == key && current.is_leaf() {
return Some((index, current));
}
}
None
}