关于生命周期的 rust 编译错误让我感到困惑。
假设代码片段如下所示:
fn process(map: &mut HashMap<String, String>, key: String) {
match map.get_mut(&key) {
Some(value) => println!("value: {}", value),
None => {
map.insert(key, String::new());
}
}
}
我这样称呼它:
fn main() {
let mut map = HashMap::<String, String>::new();
let key = String::from("name");
process(&mut map, key);
}
据我所知(忽略 NLL 功能),
map.get_mut
返回Option<&mut String>
类型,其中&mut String
是指向 map 一部分的借入指针,并且该指针贯穿整个match
块。然后在None
分支内,map.insert(key, String::new())
自动创建另一个&mut HashMap<String, String>
指针,该指针也指向 map 。这两个指针两次将相同的映射借为可变的,因此它导致:error[E0499]: cannot borrow `*map` as mutable more than once at a time
--> test.rs:7:13
|
4 | match map.get_mut(&key) {
| --- first mutable borrow occurs here
...
7 | map.insert(key, String::new());
| ^^^ second mutable borrow occurs here
8 | }
9 | }
| - first borrow ends here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0499`.
但是我的问题是:
函数
fn process
的第一个参数是一个可变的指针本身(&mut HashMap<String, String>
),它也指向 map 。根据上述规则,当下一行调用map.get_mut(&key)
时,发生第二次可变借用。为什么编译器不会抛出这样的错误(存在内存安全的风险?):fn process(map: &mut HashMap<String, String>, key: String)
--- first mutable borrow occurs here
match map.get_mut(&key)
^^^ second mutable borrow occurs here // the return value of type Option<&mut String>
我是新来的 rust ,任何技巧将不胜感激。
最佳答案
为了执行对get_mut
的调用,Rust执行隐式的重新借用。
重新借入等同于从可变引用中借用,然后将其展平。也就是说,给定可变类型&'a T
的引用,借用它会产生&'b &'a T
(请注意,存在两个不同的生存期; 'b
比'a
短),并且将引用展平会产生&'b T
。
Rust理解,生命周期为'b
的借用是从生命周期为'a
的借用派生的。因此,只要借用'a
仍然存在,就将冻结借用'b
。
在NLL之前,通过调用get_mut
获得的借用将在整个match
块中存在,因为get_mut
返回的值将使借用保持 Activity 状态。 map.insert(...)
也尝试从map
重新借入,但是由于第一次从map
重新借入仍处于 Activity 状态,所以这是一个错误。
关于rust - 为什么Rust借用检查器会忽略函数参数中的可变指针?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58577762/