r.v*_*r.v 2 generics traits rust
我正在尝试实现类似的东西,HashMap::entry但不允许使用密钥(请参阅具有类似目的的RFC )。Index impl这是我的代码,以for为模型HashMap(参见this和this)。
use std::collections::HashMap;
use std::hash::{Hash, BuildHasher};
use std::borrow::Borrow;
trait MapExt<Q: ?Sized, V> {
fn get_or_insert(&mut self, key: &Q, value: V) -> &V;
}
impl<'a, Q: ?Sized, K, V, S> MapExt<&'a Q, V> for HashMap<K, V, S>
where
K: Eq + Hash + Borrow<Q>,
Q: Eq + Hash + ToOwned,
S: BuildHasher,
{
fn get_or_insert(&mut self, key: &Q, value: V) -> &V {
if !self.contains_key(key) {
self.insert(key.to_owned(), value);
}
self[key]
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误。
use std::collections::HashMap;
use std::hash::{Hash, BuildHasher};
use std::borrow::Borrow;
trait MapExt<Q: ?Sized, V> {
fn get_or_insert(&mut self, key: &Q, value: V) -> &V;
}
impl<'a, Q: ?Sized, K, V, S> MapExt<&'a Q, V> for HashMap<K, V, S>
where
K: Eq + Hash + Borrow<Q>,
Q: Eq + Hash + ToOwned,
S: BuildHasher,
{
fn get_or_insert(&mut self, key: &Q, value: V) -> &V {
if !self.contains_key(key) {
self.insert(key.to_owned(), value);
}
self[key]
}
}
Run Code Online (Sandbox Code Playgroud)
这里出了什么问题以及如何修复它?
我认为会出现的另一个问题是编译器不知道是否Q::Owned是K。如果确实如此,我们该如何处理?
我也是一个相对初学者,但据我所知,存在三个问题:
MapExt<&'a Q, V>
Run Code Online (Sandbox Code Playgroud)
应该
MapExt<Q, V>
Run Code Online (Sandbox Code Playgroud)
否则,您将把特征类型更改为参考。
Q: Eq + Hash + ToOwned,
Run Code Online (Sandbox Code Playgroud)
应该明确地是
Q: Eq + Hash + ToOwned<Owned=K>,
Run Code Online (Sandbox Code Playgroud)
这样它就知道to_owned()将返回什么类型。
和
self[key]
Run Code Online (Sandbox Code Playgroud)
应该
&self[key]
Run Code Online (Sandbox Code Playgroud)