'Implementing Borrow trait for a type with a lifetime
I'm trying to use. strongly typed wrapper for a "keys" in my program, so that I don't mistake arbitrary strings for a Key. I have:
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Key(String);
I have a HashMap<Key, _>
, and I want to lookup values with a reference to a key type (i.e. not having to own the string). It seems like what I need to do is:
- create a "ref" type for my Key:
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct KeyRef<'a>(&'a String);
(in reality I'd want KeyRef<'a>(&'a str)
, but using String
makes for a clearer example)
- implement
Borrow<KeyRef<'_>> for Key
I've tried my best, here's a playground link
My most explicit attempt (annotating all lifetimes) is:
impl<'a> Borrow<KeyRef<'a>> for Key {
fn borrow<'b>(&'b self) -> &'b KeyRef<'a> where 'b: 'a {
let string_ref : &'a String = &self.0;
let key_ref : &'a KeyRef<'a> = &KeyRef(string_ref);
key_ref
}
}
Which gives me the error: "lifetime parameters or bounds on method borrow
do not match the trait declaration".
Intuitively it feels like this should be possible:
- KeyRef holds a reference of lifetime
'a
, so any value of KeyRef cannot outlive'a
. - In
fn borrow<'b>(&'b self)
,'b
can't be greater than'a
due to the above
But the compiler doesn't seem to like my explicit attempt to demonstrate that (with where 'b: 'a
), and leaving it off I get "cannot infer an appropriate lifetime for borrow expression due to conflicting requirements"
Solution 1:[1]
As far as I understand your situation, you are needlessly overcomplicating things. A straightforward implementation:
use std::collections::HashMap;
use std::borrow::Borrow;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Key(String);
impl Borrow<str> for Key {
fn borrow(&self) -> &str {
&self.0
}
}
impl Borrow<String> for Key {
fn borrow(&self) -> &String {
&self.0
}
}
fn main() {
let mut map = HashMap::new();
map.insert(Key("one".to_owned()), 1);
// Because Key is Borrow<String>
println!("{:?}", map.get("one".to_owned()));
// Because Key is Borrow<str>
println!("{:?}", map.get("one"));
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | user2722968 |