无法移出 `current`,因为它是在从递归返回时借用的

问题描述 投票:0回答:1

让我们考虑一下我的存储结构,其中包含 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 行借用了键,只要“键”引用存在,即直到它们在方法调用后被删除,但我的问题是在算法中处理此问题的惯用方法是什么?特别是不克隆对象,这对我来说听起来像是一种解决方法?

rust borrow-checker
1个回答
0
投票

我认为你的例子中一定遗漏了一些重要的东西。它不能按原样编译。

更改它以解决最明显的问题,并从通过

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
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f0ae75422458645b6521ac3803f0411c

© www.soinside.com 2019 - 2024. All rights reserved.