首页 > 解决方案 > Trie: cannot borrow `_` as mutable more than once at a time

问题描述

I want to implement some basic methods for 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(),
                value: None,
            });
        }
        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,
        }
    }
}

The method delete is to remove a key (from a Trie) and returns the value corresponding to that key. However, I got the following error.

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

标签: data-structuresrusttrie

解决方案


As the error message explains, you cannot borrow a value (current_node.chs) as mutable more than once at a time.

One solution is to derive the Clone trait for TrieNode. Clone is a common trait for the ability to explicitly duplicate an object:

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

Now instead of borrowing self.root, you can clone it:

fn delete(&mut self, key: &String) -> Option<i32> {
  if key.is_empty() { 
    return None
  }
  // clone `self.root`
  let mut current_node = self.root.clone();
  for (ind, ch) in key.chars().enumerate() {
  match current_node.chs.get_mut(&ch) {
    Some(node) => {
      if ind < key.len() - 1 {
      // clone `node`
        current_node = node.clone();
      }
    // ...

If performance is an issue, then cloning is probably not the best idea. However, it is still an option and may or may not suit your use case.


推荐阅读