微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试:一次不能多次借用_变量

如何解决尝试:一次不能多次借用_变量

我想为Trie实现一些基本方法

use std::collections::HashMap;

#[derive(Debug)]
struct TrieNode {
    chs: HashMap<char,TrieNode>,value: Option<i32>,}

#[derive(Debug)]
struct Trie {
    root: TrieNode,}

impl Trie {
    fn new() -> Trie {
        Trie {
            root: TrieNode {
                chs: HashMap::new(),value: None,},}
    }

    fn add_string(&mut self,string: String,value: i32) {
        let mut current_node = &mut self.root;
        for c in string.chars() {
            current_node = current_node.chs.entry(c).or_insert(TrieNode {
                chs: HashMap::new(),});
        }
        current_node.value = Some(value);
    }

    fn delete(&mut self,key: &String) -> Option<i32> {
        if key.is_empty() {
            // if key is empty,no need to delete
            return None;
        }
        let mut current_node = &mut self.root;
        for (ind,ch) in key.chars().enumerate() {
            match current_node.chs.get_mut(&ch) {
                Some(node) => {
                    if ind < key.len() - 1 {
                        current_node = node;
                    }
                }
                None => return None,}
        }
        // here current_node is actually the prevIoUs node of the deleted node
        let temp = current_node.chs.remove(&key.chars().last().unwrap());
        match temp {
            Some(node) => node.value,None => None,}
    }
}

方法delete是(从Trie中)删除一个键并返回与该键对应的值。但是,出现以下错误

error[E0499]: cannot borrow `current_node.chs` as mutable more than once at a time
   --> src/main.rs:118:19
    |
118 |             match current_node.chs.get_mut(&ch) {
    |                   ^^^^^^^^^^^^^^^^ mutable borrow starts here in prevIoUs iteration of loop

解决方法

如错误消息所述,您一次不能多次借用可变的值(current_node.chs)。

一种解决方案是派生Clone的{​​{1}}特征。 TrieNode是显式复制对象的一个​​共同特征:

Clone

现在,您无需克隆#[derive(Debug,Clone)] struct TrieNode { chs: HashMap<char,TrieNode>,value: Option<i32>,} ,就可以克隆它:

self.root

如果性能是一个问题,那么克隆可能不是最好的主意。但是,它仍然是一种选择,可能会也可能不适合您的用例。

,

我不确定借款检查器在哪里被绊倒,但是您可以通过举起if支票来解决它:

    let mut current_node = &mut self.root;
    for (ind,ch) in key.chars().enumerate() {
        if ind < key.len() - 1 {
            match current_node.chs.get_mut(&ch) {
                Some(node) => {
                    current_node = node;
                }
                None => return None,}
        }
    }

它甚至跳过检查叶节点是否存在,但是您的remove(匹配项已经涵盖了这种情况。


此外,您的ind < key.len() - 1检查假设最后一个字符是ascii。对于您的用例来说可能是正确的,但如果不是,则可以使用this answer进行迭代,直到倒数第二个字符为止。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。