HashMap Entry() 方法使借用时间比预期长

Nav*_*mar 3 rust borrow-checker

我刚刚开始学习 Rust,遇到了HashMap 的 entry() 方法看似奇怪的行为。在下面的示例中,该方法采用可变引用并返回Entry 枚举。我什至没有捕获并保留返回的值。但是借用检查器似乎认为下一次迭代开始时对“s”的可变引用仍然在范围内。

let mut window: HashMap<&String, i32> = HashMap::new();
let mut s = "help_me".to_string();
loop {
    let p = &mut s;        // ERROR
    window.entry(p);
}
Run Code Online (Sandbox Code Playgroud)

这显示了片段恐慌并出现错误:

Line 27, Char 26: cannot borrow `s` as mutable more than once at a time (solution.rs)
   |
27 |             window.entry(&mut s);
   |                          ^^^^^^ `s` was mutably borrowed here in the previous iteration of the loop
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下这种行为吗?

Cha*_*man 6

地图的键类型是&String。我们称之为一生&'a String

entry()方法可能需要将密钥插入到地图中(这是入口 API 的全部思想)。因此,它采用与键相同的类型,即&'a String

当你借钱时s,你需要借钱持续下去,'a这样你才能&'a String从中获得。所以,你可以可变地借用它'a

But the next time the loop is executing, while 'a is still active (because the map is still alive), you borrow s again, again for 'a, while it is already mutably borrowed for 'a so you cannot borrow it during that time. This is the error.

You probably want a map of String (not &String), or, even if you do want references, you can instead of doing window.entry(&mut s); to do window.entry(&s); and then it will work because you can borrow a value for a shared reference multiple times.

  • @NaveenSanthanavel 但是当返回的枚举超出范围时,键可能已经插入到映射中。借用检查器无法跟踪这一点。 (2认同)