Я пишу функцию, которая работает с HashMap
, и в различных точках функции я хочу проверить, соответствует ли какое-либо из значений на карте условию, и если оно есть, возвращает ключ только для одного из записи, соответствующие условию.
До сих пор я пытался сначала выполнить итерации по ссылкам, чтобы проверить мое состояние, а затем использовать remove_entry
для получения собственной копии ключа, а не заимствования:
use std::{collections::HashMap, hash::Hash};
fn remove_first_odd<K: Hash + Eq>(map: &mut HashMap<K, u64>) -> Option<K> {
let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1);
match maybe_entry {
Some((key_ref, _value_ref)) => {
let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap();
Some(key_owned)
}
None => None,
}
}
но это не проходит проверку заимствования, потому что я не могу изменить карту, пока я все еще держу ссылку на один из ключей в ней:
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> src/lib.rs:8:45
|
4 | let maybe_entry = map.iter().find(|(_, &value)| value & 1 == 1);
| --- immutable borrow occurs here
...
8 | let (key_owned, _value_owned) = map.remove_entry(key_ref).unwrap();
| ^^^^------------^^^^^^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
Я считаю, что это возможно, поскольку до тех пор, пока remove_entry
только разыменовывает мой ключ до мутации, а не после, это должно быть нормально.
Так есть ли безопасный API для этого? Если нет, то можно ли его создать?
Обратите внимание, что:
- Я не могу клонировать свои ключи, потому что они являются общими без привязки клону
- Я не могу потреблять
HashMap
с чем-то вроде .into_iter()
- Мне нужно удалить только одну запись, а не все записи, которые соответствуют