I would like to have a struct:
struct AllCaches {
vectors: HashMap<usize, Cache<T>>,
}
The purpose of AllCaches
is to hold various bits of useful information relating to Cache
s which are typed (<T>
).
Clearly, this isn't valid code, since I would need to specify <T>
in my AllCaches
declaration. I can't do that since the AllCaches
struct is intended to hold all my caches irrespective of their <T>
.
My current solution involves a trait which I implement as:
struct AllCaches {
vectors: HashMap<usize, Box<dyn CacheTrait>>,
}
I have managed to make this work, but it involves a lot of nasty/messy down casting and horrible looking code such as:
let data;
if let Some(thing) = caches.downcast_ref::<Cache<u64>>() {
debug!("U64");
data = VectorType::U64(thing.populate_vector(&req.index, &mvector));
} else if let Some(thing) = caches.downcast_ref::<Cache<f64>>() {
debug!("F64");
data = VectorType::F64(thing.populate_vector(&req.index, &mvector));
}
(using downcast-rs crate to achieve the down casting).
The impact on my code is that I need a lot of very repetitive (<T>
) specific functionality and the benefit of having a generic type seems to be lost.
This seems horrible to me and I feel like there must be a better answer.
I've wrestled with this for a week (on and off) and investigated other options such as using enums, but that didn't seem to improve the situation (although, maybe I didn't understand that approach completely). I've done a lot of googling and reading documentation, I'm fairly inexperience with Rust, but not made much progress.