Rust Tree 实现借用问题

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

我是 Rust 新手,想编写一些代码来提升它的水平。现在我正在编写一个简单的 B 树实现,并且遇到了可变引用的问题。

use std::fmt::Debug;

#[allow(dead_code)]
#[derive(Clone, Debug)]
struct Node<T: PartialOrd + Clone + Debug> {
    leaf: bool,
    count: usize,
    keys: Vec<T>,
    children: Vec<Box<Node<T>>>,
    t: usize,
}

#[allow(dead_code)]
impl<T: PartialOrd + Clone + Debug> Node<T> {
    fn empty(t: usize) -> Self {
        return Node {
            keys: Vec::with_capacity(t),
            children: Vec::with_capacity(t + 1),
            count: 0,
            leaf: false,
            t,
        };
    }

    fn leaf(t: usize) -> Self {
        return Node {
            keys: Vec::with_capacity(t),
            children: Vec::with_capacity(t + 1),
            count: 0,
            leaf: true,
            t,
        };
    }
   
    /**
     * return siblings of node with given index
     * first element is given node
     */
    fn siblings(&mut self, index: usize) -> Vec<&mut Box<Node<T>>> {
        let mut result: Vec<_> = self
            .children
            .iter_mut()
            .enumerate()
            .filter(|(i, _)| *i == index || *i + 1 == index || *i == index + 1)
            .map(|(_, v)| v)
            .collect();

        if result.len() == 3 {
            result.swap(0, 1);
        } else {
            if index == 0 {
                result.swap(0, 1);
            }
        }

        result
    }

    fn remove_key(&mut self, key: T) -> bool {
        let result = self.keys.iter().position(|element| *element == key);

        match result {
            None => false,
            Some(index) => {
                self.keys.remove(index);

                return true;
            }
        }
    }

    /**
     * self refers to root of leaf
     * i is index of child, where we want to remove value
     * returns status of operation: did element remove
     */
    fn delete_from_leaf(&mut self, value: T, i: usize) -> bool {
        let t = self.t;
        let mut siblings = self.siblings(i);
        let target_leaf = siblings.remove(0);

        if target_leaf.count >= t {
            return target_leaf.remove_key(value);
        }

        if siblings.is_empty() {
            return false;
        }

        while siblings.len() > 0 {
            let current_node = siblings.remove(0);

            if current_node.count < t {
                continue;
            }

            let max_value = current_node.keys.pop().unwrap();
            let delimeter_value = self.keys.remove(i);

            target_leaf.keys.insert(0, delimeter_value);
            self.keys.insert(i, max_value);

        }

        true
    }
}

货物检查:

error[E0499]: cannot borrow `self.keys` as mutable more than once at a time
   --> src/main.rs:212:35
    |
193 |         let mut siblings = self.siblings(i);
    |                            ---------------- first mutable borrow occurs here
...
204 |         while siblings.len() > 0 {
    |               -------------- first borrow later used here
...
212 |             let delimeter_value = self.keys.remove(i);
    |                                   ^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here

error[E0499]: cannot borrow `self.keys` as mutable more than once at a time
   --> src/main.rs:215:13
    |
193 |         let mut siblings = self.siblings(i);
    |                            ---------------- first mutable borrow occurs here
...
204 |         while siblings.len() > 0 {
    |               -------------- first borrow later used here
...
215 |             self.keys.insert(i, max_value);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here

For more information about this error, try `rustc --explain E0499`.

如何更改

self.keys
功能中的
delete_from_leaf
?据我了解,第一个可变引用位于
self.siblings()
中,但它根本不访问 self.keys 。我应该在这里使用
unsafe {}
块吗?或者重新编写更底层的代码。 我编写了
fn self.siblings()
来访问
self.children
Vec 中的多个 mut 引用。有更好的办法吗?

rust borrow-checker
© www.soinside.com 2019 - 2024. All rights reserved.