gpt4 book ai didi

rust - 为什么 Rust borrow checker 会忽略函数参数中的可变指针?

转载 作者:行者123 更新时间:2023-11-29 08:25:57 24 4
gpt4 key购买 nike

我只是对有关生命周期的 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 执行了一个隐式的reborrow

reborrow 相当于从可变引用中借用,然后将引用展平。也就是说,给定类型为 &'a T 的可变引用,从中借用会产生 &'b &'a T(请注意,有两个不同的生命周期;'b'a 短),并且将引用展平会产生 &'b T

Rust 理解生命周期 'b 的借用是从生命周期 'a 的借用派生的。因此,只要 borrow 'b 还活着,borrow 'a 就会被卡住。

在 NLL 之前,为调用 get_mut 获得的借用将在整个 match block 中存在,因为 get_mut 返回一个值来保持借活跃。 map.insert(...) 也尝试从 map 重新借用,但是由于从 map 的第一次重新借用仍然有效,这是一个错误.

关于rust - 为什么 Rust borrow checker 会忽略函数参数中的可变指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58577762/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com