Hello all.
I have a struct which, among other things, owns a string called name. I have another struct which stores a hashmap of the previous struct. Something like:
struct Foo { name: String }
struct FooMgr { foos: HashMap<String, Foo> }
While this works, it involves additional cloning of Foo.name to act as a key in the hashmap.
What I really want is something like:
struct FooMgr { foos: HashMap<&str ,Foo> }
But I am stuck on how to deal with the lifetime for the &str in my add_foo method, since I want to associate it with Foo and not FooMgr. Can someone point me at an example or docs which would be relevant?
2 Likes
In short, what you're attempting to do will create a self-referential struct.
To side step this, you can share the ownership of the string between the HashMap and the Foo:
struct Foo { name: Rc<str> }
struct FooMgr { foos: HashMap<Rc<str>, Foo> }
If you just want to look up the Foos by name, consider using a HashSet<Foo>
, which you can query via HashSet::get
. This method allows you to pass something that Foo
can be borrowed as, so if you make it impl Borrow<str>
for example, you can look them up by string slices.
2 Likes
Thanks vitalyd. I actually went down that road initially. Unfortunately, I hit an issue with my inability to call contains_key with a &str:
playground example
Yes, I remember this has bitten me as well, but as @vitalyd said, the trick is to use Rc<str>
.
You can do it like this: Rust Playground
1 Like
Separately but relatedly, it seems like an omission that Rc<String>
doesn’t impl Borrow<str>
.
2 Likes
Vitalyd, birkenfeld, thank you both!