我如何解决"不能借用`* self`作为可变因为`self.bundles`也被借用为不可变的"在以下背景下?

时间:2017-11-14 12:51:17

标签: compiler-errors rust immutability mutable borrow-checker

我的lib.rs

中有以下代码
extern crate serde;
extern crate serde_json;
extern crate build_script_file_gen;

use serde_json::Value;
use serde_json::from_str;
use std::fs::File;
use std::io::Read;
use std::collections::HashMap;

pub enum ConfigurationSource {
    StringContent(String),
    FileContent(String)    
}

pub struct ConfigurationBuilder {
    config: Value,
    bundles: HashMap<String, Vec<ConfigurationSource>>    
}

impl<'a> ConfigurationBuilder{

    pub fn new(base_source: ConfigurationSource) -> ConfigurationBuilder{
        let base_config: Value = from_str("{}").unwrap();

        let mut config_builder = ConfigurationBuilder{
            config: base_config,
            bundles: HashMap::new()
        };

        config_builder.merge_source(&base_source);

        return config_builder;
    }

    pub fn merge_sources(&mut self, config_sources: &Vec<ConfigurationSource>){        
        for source in config_sources{
            self.merge_source(source);
        }
    }

    pub fn merge_source(&mut self, config_source: &ConfigurationSource){            
        match config_source {
            &ConfigurationSource::StringContent(ref content) => {                
                let config_override: Value = from_str(&content[..]).unwrap();
                merge(&mut self.config, config_override);
                //merge(&mut config, &json_override);
            },
            &ConfigurationSource::FileContent(ref path) => {
                let mut config_file = File::open(path).unwrap();
                let mut config_file_content = String::new();
                config_file.read_to_string(&mut config_file_content).unwrap();

                let config_override: Value = from_str(&config_file_content[..]).unwrap();
                merge(&mut self.config, config_override);
            }
        }      
    }

    pub fn merge_bundle(&mut self, bundle_key: &str){
        let sources = self.bundles.get(bundle_key).unwrap();
        self.merge_sources(sources);
    }
}

fn merge(a: &mut Value, b: Value) {
    match (a, b) {
        (a @ &mut Value::Object(_), Value::Object(b)) => {
            let a = a.as_object_mut().unwrap();
            for (k, v) in b {
                merge(a.entry(k).or_insert(Value::Null), v);
            }
        }
        (a, b) => *a = b,
    }
}

编译时出现以下错误

error[E0502]: cannot borrow `*self` as mutable because `self.bundles` is also borrowed as immutable
  --> src/lib.rs:62:9
   |
61 |         let sources = self.bundles.get(bundle_key).unwrap();
   |                       ------------ immutable borrow occurs here
62 |         self.merge_sources(sources);
   |         ^^^^ mutable borrow occurs here
63 |     }
   |     - immutable borrow ends here
  1. 语句let sources = self.bundles.get(bundle_key).unwrap();如何暗示不可变借用?
  2. self如何可变借款?即self未使用let mut
  3. 分配给此处的任何变量
  4. 如何避免上述编译错误。请注意,如果我注释掉整个merge_bundle方法实现,它会成功编译。

0 个答案:

没有答案