这段代码编译(游乐场链接):
use std::collections::HashMap;
fn main() {
let mut h = HashMap::<char, Vec<i32>>::new();
h.insert('a', vec![0]);
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
}
使用借用(push()
调用)更改代码的顺序...
let first_borrow = h.get_mut(&'a').unwrap();
let second_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
second_borrow.push(2);
...使其无法编译:
error[E0499]: cannot borrow `h` as mutable more than once at a time
--> src/main.rs:8:25
|
7 | let first_borrow = h.get_mut(&'a').unwrap();
| - first mutable borrow occurs here
8 | let second_borrow = h.get_mut(&'a').unwrap();
| ^ second mutable borrow occurs here
9 | first_borrow.push(1);
| ------------ first borrow later used here
而且,使用first_borrow
过去的实例化second_borrow
也不会编译:
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
// ...
first_borrow.push(1);
考虑到文档中关于范围的说法,这令人惊讶。在编译的代码中,为什么我们那里也没有两个可变借项?
在这个例子中,编译,不会锈看到,之后let second_borrow = ...
,有没有更多提及first_borrow
的任何地方,因此它unborrows的可变借first_borrow
,从而保留了单键借在整个范围的main()
?!
简短的答案是,同一数据的两个可变借用不能同时在范围内,并且第一个示例不违反该限制。请注意,这是可变引用的“一个大限制”的推论,即“您只能在特定范围内对特定数据段进行一个可变引用”。请参阅“ Rust编程语言”中的“参考和借阅”部分。
第一个示例编译是因为first_borrow
超出范围才second_borrow
进入范围。“超出范围”与在其余范围中未引用的变量同义。我不知道底层的细节,但是这就是我对这个示例的看法。
// first_borrow comes into scope
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
// first_borrow goes out of scope
// second_borrow comes into scope
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
// second_borrow goes out of scope
对于不编译你的第二个例子中,我们可以看到,作用域first_borrow
和second_borrow
交叉。
// first_borrow comes into scope
let first_borrow = h.get_mut(&'a').unwrap();
// second_borrow comes into scope
let second_borrow = h.get_mut(&'a').unwrap();
// !!! both first_borrow and second_borrow are in scope now !!!
first_borrow.push(1);
// first_borrow goes out of scope
second_borrow.push(2);
// second_borrow goes out of scope
实际上,是的。我不认为这是无聊的。如上所述,我相信这个词first_borrow
超出了范围。
例如,您可能会这样编写第一个示例。
{
let first_borrow = h.get_mut(&'a').unwrap();
first_borrow.push(1);
}
{
let second_borrow = h.get_mut(&'a').unwrap();
second_borrow.push(2);
}
当然,第二个示例不能以这种方式编写,因为借用是相互交叉的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句