-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can get() take an AsRef/Borrow? #26
Comments
Hi, this is a great question! I tried playing around to see what I could come up with, but I'm currently stumped. Following your lead on pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
let key = KeyRef { k }; // <-- Need to make this step unnecessary
let (node_ptr, value) = match self.map.get_mut(&key) {
...
} I tried to solve that problem first, since it seemed to me that if we aren't able to pass the reference to the key directly to the internal map then passing a reference to a different certainly won't be possible. By implementing impl<K> Borrow<K> for KeyRef<K> {
fn borrow(&self) -> &K {
unsafe { &(*self.k) }
}
}
pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
let (node_ptr, value) = match self.map.get_mut(k) {
...
} From there, I tried to make the // This fails to compile with the following error:
// conflicting implementations of trait `std::borrow::Borrow<KeyRef<_>>` for type `KeyRef<_>`:
//
// note: conflicting implementation in crate core:
//
// - impl<T>; std::borrow::Borrow<T>; for T
// where T: ?Sized;
impl<J, K: Borrow<J>> Borrow<J> for KeyRef<K> {
fn borrow(&self) -> &J {
unimplemented!()
}
}
pub fn get<'a, Q>(&'a mut self, k: &Q) -> Option<&'a V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
let (node_ptr, value) = match self.map.get_mut(k) {
...
} The compiler can't accept the implementation of impl<'_, T> Borrow<T> for &'_ mut T
where
T: ?Sized I think I can understand the conflict because if I put up my current work in #27 if you get a chance to take a look. I would certainly welcome any feedback. |
LruCache
isn't quite a drop-in replacement forHashMap
for me, as I'm usingHashMap<String, i64>
. For this type,.get("some &str")
works. This avoids the copy/allocation ofto_string()
.For
LruCache
, you instead get this error:I had a go at changing the code to be more like HashMap's (and take a
Borrow
), but I got lost. Here's my thoughts: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0e81344c5da15c2b7c5f24e3135e7551The issue is the
KeyRef
, where aKeyRef<String>
isn't similar enough to aKeyRef<str>
. I believe aString
is only similar-enough to astr
due to pointer abuse, eventually inside:The same construct appears inside e.g.
PathBuf -> Path
's implementation. 😱Can anyone think of a way to make this work?
The text was updated successfully, but these errors were encountered: