I have a Vec<Box> and id like to store all my widgets in here for rendering but id also like to keep references to certain widgets. When i push the widgets into my vector they are moved and the borrow checker complains when i try to reference them. How can i get around this?
-
1Please include a [mre]. Without it, there's no way to help you other than random guessing. – Aplet123 Feb 28 '21 at 12:10
-
1Likely duplicate of [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/q/32300132/3650362) – trent Feb 28 '21 at 12:36
-
If the vector is never reordered or shrunk, just use `usize` instead of `&T` and index into the `Vec` instead of dereferencing it. – trent Feb 28 '21 at 12:39
1 Answers
The issue you're seeing here is that you cannot mutate the vector while alos having references into it. This is a good guard to have as it can lead to dangling references.
There are a few ways to fix this, the first being reference counting with either Rc
or Arc
. This mutates your vector to be Vec<Rc/Arc<WidgetType>>
or Vec<Rc/Arc<&dyn WidgetTrait>>
if you're doing virtual calls. Then instead of referencing those widgets elsewhere you clone the reference counter. This can be done relativly easily but has the downsides of there being a pointer indirection added and the items can still exist even if they're removed from your render queue.
The next option is to store indexes/keys into the render list. This can be done with usize
on a Vec
as @trentcl said in the comments or an arbitray key with HashMap
. This has the downsides of index movement in the case of a vector or a lot of hashing with a hashmap.
The best option in my opinion requires a library but covers all the other downsides. The library is slotmap. This creates a map with a vector backing that returns keys that you can replace your references with. There are a few options within it as to how you want the data to be stored and which opertions you want to be optimized, but that can all be seen in the documentaion. The main issue with this is that you have to add a dependancy which may not be preferable depending on your specific case.

- 443
- 3
- 7