Rust:多次借用结构实例失败,即使使用了范围,也失败

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

我正在尝试创建一个包含哈希图和向量的struct,因此vector应该包含hashmap中的对值的引用

我认为,当放入独立的scopes中时,可以在同一实例上进行多个可变借用。

([Playground

use std::collections::HashMap;

struct Container<'a> {
    map: HashMap<String, String>,
    vec: Vec<&'a String>
}

impl<'a> Container<'a> {
    pub fn new() -> Self {
        Container {
            map: HashMap::new(),
            vec: Vec::new()
        }
    }

    pub fn add_link(&'a mut self, key: &str) {
        if let Some(value) = self.map.get(key) {
            self.vec.push(value);
        }
    }

    pub fn print_vec(&self) {
        println!("Vec: {:?}", self.vec);
    }
}

fn main() {
    let mut container = Container::new();

    {
        container.map.insert("a".to_string(), "x".to_string());
    }
    {
        container.map.insert("b".to_string(), "y".to_string());
    }
    {
        container.map.insert("c".to_string(), "z".to_string());
    }

    {
        container.add_link("c");
    }
    {
        container.add_link("a");
    }
    {
        container.add_link("c");
    }
    {
        container.add_link("k");
    }

    container.print_vec();
}
error[E0499]: cannot borrow `container` as mutable more than once at a time
  --> src/main.rs:44:9
   |
41 |         container.add_link("c");
   |         --------- first mutable borrow occurs here
...
44 |         container.add_link("a");
   |         ^^^^^^^^^
   |         |
   |         second mutable borrow occurs here
   |         first borrow later used here


(...)

我期望输出为:Vec: ["z", "x", "z"]

struct rust mutable borrow-checker borrowing
1个回答
0
投票

tl; dr

不是 (至今1.41.1) 实现自引用结构很简单。

[就像@SCappella提到的那样,已经有更详细的方法解决此问题here


我解决问题的方法是通过将我的容器结构拆分为两个单独的结构来绕过原始问题,其中引用结构与数据拥有结构分开。

([Playground

use std::collections::HashMap;

struct Container {
    map: HashMap<String, String>,
}

struct DependentContainer<'a> {
    vec: Vec<&'a String>,
}

impl Container {
    pub fn new() -> Self {
        Container {
            map: HashMap::new(),
        }
    }

    pub fn add(&mut self, key: &str, value: &str) {
        self.map.insert(key.to_string(), value.to_string());
    }
}

impl<'a> DependentContainer<'a> {
    pub fn new() -> Self {
        DependentContainer {
            vec: Vec::new()
        }
    }

    pub fn add_link(&mut self, container: &'a Container, key: &str) {
        if let Some(value)= container.map.get(key) {
            self.vec.push(value);
        }
    }

    pub fn print_vec(&self) {
        println!("Vec: {:?}", self.vec);
    }
}

fn main() {
    let mut container = Container::new();
    let mut dep_container = DependentContainer::new();

    container.add("a", "x");
    container.add("b", "y");
    container.add("c", "z");

    dep_container.add_link(&container, "c");
    dep_container.add_link(&container, "a");
    dep_container.add_link(&container, "c");
    dep_container.add_link(&container, "k");

    dep_container.print_vec();
}
© www.soinside.com 2019 - 2024. All rights reserved.