Объявление функции HashMap::<K,V>::get()
немного упрощено:
pub fn get<'s>(&'s self, k: &K) -> Option<&'s V>
Это означает, что он возвращает необязательную ссылку на содержащееся значение, а не само значение. Поскольку возвращенная ссылка указывает на значение внутри карты, она фактически заимствует карту, то есть вы не можете изменить карту, пока эта ссылка существует. Это ограничение защищает вас, что произойдет, если вы удалите это значение, пока ссылка еще жива?
Итак, когда вы пишете:
match self.t.get(&v) {
None => false,
//r: &u16
Some(r) => self.remove(r)
}
захваченный r
имеет введите &u16
, а его время жизни равно self.t
, то есть оно заимствует его. Таким образом, вы не можете получить изменяемую ссылку на self
, которая необходима для вызова remove.
Самое простое решение вашей проблемы - clone()
решает каждую жизненную проблему шаблон. Так как ваши значения имеют тип u16
, то есть Copy
, это на самом деле тривиально:
match self.t.get(&v) {
None => false,
//r: u16
Some(&r) => self.remove(&r)
}
Теперь r
на самом деле имеет тип u16
, поэтому он ничего не заимствует, и вы можете изменять self
по желанию.
Если ваши типы ключей / значений не были Copy
, вы можете попробовать и clone
их, если вы готовы за это заплатить. Если нет, есть еще один вариант, так как ваша функция remove()
не изменяет HashMap
, а не связана HashSet
. Вы все еще можете изменить этот набор, если вы позаботитесь о том, чтобы не заимствовать self
:
fn remove2(v: &u16, l: &mut HashSet<u16>) -> bool {
l.remove(v)
}
fn do_work(&mut self, v: u16) -> bool {
match self.t.get(&v) {
None => false,
//selt.t is borrowed, now we mut-borrow self.l, no problem
Some(r) => Self::remove2(r, &mut self.l)
}
}