【问题标题】:Borrow a hashmap without Borrowing his content借用哈希图而不借用他的内容
【发布时间】:2020-09-19 14:34:57
【问题描述】:

我是 rust 新手,我已阅读有关所有权和借款的文档。显然,我开始在这个概念上挣扎......

这是我的代码:


#[derive(Serialize, Deserialize, Debug)]
pub struct City {
    name: String,
    dep: String,
    dynamic: String,
    population: u64, 
    cp: String,
    price_max: u8,
    price_mid: u8,
    price_min: u8,
    lng: f64,
    lat: f64,
    dist_near_city: Vec<(String, u64)>
}

fn load_cities<P: AsRef<Path>>(path: P) -> HashMap<String, City> {
    // Open the file in read-only mode with buffer.
    let file = File::open(path).expect("Unable to open file");
    let reader = BufReader::new(file);
    let retval: HashMap<String, City> = serde_json::from_reader(reader).expect("Unable to parse json");

    return retval;
}

fn update_nearby_cities(pin_city: &mut City, cities : &HashMap<String, City>, min_pop: u64, distKm: f64){
    pin_city.dist_near_city = Vec::new();
    for (id, city) in cities {
        if city.population > min_pop && is_nearby(&pin_city, &city, distKm){
            pin_city.dist_near_city.push((id.to_string(), city.population));
        }
    }
}


fn main(){
    let path  = "/home/marcel/Documents/immobilier/cities_export2.json";
    let mut cities = load_cities(path);

    for (cp, mut current_city) in &cities {
        update_nearby_cities(&mut current_city, &cities, 2000, 10.);
    }
}

我在 main() 的循环中得到了 arg &amp;mut current_city 的错误:

cannot borrow data in a&reference as mutable

首先,我不明白为什么我不能借用可变引用,因为它在我的代码的其他部分和文档中是可能的 (https://doc.rust-lang.org/rust-by-example/scope/borrow/mut.html)

我认为这是因为&amp;cities 上的循环给了我一个current_city: &amp;City 并且通过给&amp;mut current_city 我传递了一个&amp;mut &amp;City 这是一个问题(我不知道如何处理这种类型,我不知道'甚至认为我不明白这是什么东西......)。

所以如果我尝试只传递mut current_city,我会得到Exepted expression

我预见的另一个问题是,我试图借用循环中引用的 hashmap 并在循环内重新借用它。

如何正确地做这种事情,我对错误的想法是否正确?

【问题讨论】:

    标签: rust


    【解决方案1】:

    for entry in &amp;cities 在 (&K, &V) 上提供一个迭代器。如果您需要 (&K, &mut V) 上的迭代器,请使用 `&mut city'

    即使使用此更改代码也不起作用。您正在尝试同时迭代和修改cities

    一种无需进行大量重构的简单方法是一次计算所有结果,然后稍后将它们添加到哈希图中。

    fn get_nearby_cities(pin_city: &City, cities : &HashMap<String, City>, min_pop: u64, distKm: f64) -> Vec<(String, u64)> {
        let mut dist_near_city = Vec::new();
        for (id, city) in cities {
            if city.population > min_pop && is_nearby(&pin_city, &city, distKm){
                dist_near_city.push((id.to_string(), city.population));
            }
        }
    
        dist_near_city
    }
    
    
       # Compute all the required results. Unfortunately, I ended up clone the string. May be this could be avoided.
       let mut result = HashMap::new();
        for (cp, current_city) in &cities {
            result.insert(cp.clone(), get_nearby_cities(current_city, &cities, 2000, 10.));
        }
    
        for (city, nearby_cities) in result {
            cities.get_mut(&city).unwrap().dist_near_city.extend(nearby_cities);
        }
    

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 2016-05-02
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      相关资源
      最近更新 更多