Мне нужна функция, которая защищает мои HashMap
от перезаписи уже существующих значений, поэтому я написал простую функцию, подобную этой:
fn insert_or_panic<K, V>(m: &mut HashMap<K, V>, k: K, v: V)
where
K: Hash + Eq,
{
use std::collections::hash_map::Entry;
match m.entry(k) {
Entry::Vacant(o) => o.insert(v),
Entry::Occupied(_) => panic!("attempt to overwrite entry in dictionary"),
};
}
Теперь я хочу обобщить ее для работы с любым видомmap:
fn generic_insert_or_panic<M, K, V>(m: &mut M, k: K, v: V)
where
K: Hash + Eq,
M: Map<K, V>,
{
use std::collections::hash_map::Entry;
match m.entry(k) {
Entry::Vacant(o) => o.insert(v),
Entry::Occupied(_) => panic!("attempt to overwrite entry in dictionary"),
};
}
Все интересующие меня методы HashMap
находятся в его блоке impl
, не связанном с какой-либо чертой, поэтому похоже, что мне нужно реализовать новую черту:
trait Map<K: Hash + Eq, V> {
fn entry(&mut self, key: K) -> Entry<K, V>;
}
Каждая карта имеет свой собственный тип Entry
: std::collections::hash_map::Entry
или std::collections::btree_map::Entry
, и я не вижу подходящей черты для замены Entry
.Настало ли время для другой черты?
Я чувствую, что иду не в ту сторону.Как решить эту проблему?
Я только начал изучать Rust, и некоторые из моих проблем могут выглядеть нереально и надуманными, но я ищу способы решения проблем, а не обходить ихили, по крайней мере, знать ограничения языка.
FAQ объясняет , что типы с более высоким родом могут решить эту проблему, но это большая особенность, так что ржавчина хочетподходите к нему осторожно.