Меня просто смутила ошибка компиляции ржавчины о времени жизни.
Предположим, фрагмент кода выглядит следующим образом:
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
- это указатель заимствования, который указывает на часть карты, ауказатель живет через весь блок match
. Затем внутри ветви None
, map.insert(key, String::new())
автоматически создает еще один указатель &mut HashMap<String, String>
, который также указывает на карту. Два указателя занимают одну и ту же карту дважды как изменяемую, поэтому она вызывает:
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.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>
Я новичок в ржавчине, любые советы будут оценены.