Why does the borrow from `HashMap::get` not end when the function returns?

若如初见. 提交于 2019-12-02 20:31:33

问题


Here is emulation of my problem, when a borrow ends too late

use std::collections::HashMap;

struct Item {
    capacity: u64
}

struct Petrol {
    name: String,
    fuel: HashMap<&'static str, Item>
}

fn buy_gaz(p: &mut Petrol) {
   match p.fuel.get("gaz") {
      Some(gaz) => {
        fire_petrol(p); 
      }
      None => ()
   }
}

fn fire_petrol(p: &mut Petrol) {
    println!("Boom!");
    p.fuel.remove("gaz");
    p.fuel.remove("benzin");
}

fn main() {
    let mut bt = Petrol {
        name: "Britii Petrovich".to_string(),
        fuel: HashMap::new()
    };

    bt.fuel.insert("gaz", Item { capacity: 1000 });
    bt.fuel.insert("benzin", Item { capacity: 5000 });

    buy_gaz(&mut bt);
}

When compiling I get:

note: previous borrow of `p.fuel` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `p.fuel` until the borrow ends
match p.fuel.get("gaz") {
      ^~~~~~

Why does the borrow end so late and not on exit from HashMap::get? How do I fix my case?

PS: I edited my first post for adding struct to HashMap, because decision below worked for simply types (with default Clone trait, I think), but doesn't work for custom structures


回答1:


If you look at the documentation of HashMap::get you can see, that it returns an Option<&V>. The reference into the map allows you to do zero-copy accesses into a hash-map. The downside is, as long as you have a reference, you cannot modify the hash map as that might invalidate your reference.

The branch Some(gaz) causes the binding gaz to have type &u64, where the reference points into your hashmap. If you change that to Some(&gaz) you get a copy of the value instead of a reference, and may modify the hash map even inside that branch.

Minimal Example in Playpen



来源:https://stackoverflow.com/questions/29561696/why-does-the-borrow-from-hashmapget-not-end-when-the-function-returns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!