I have different structs which all contain a HashMap
with String
as the key, but with different value types. For example, one struct has a member of type HashMap<String, String>
, the other will have a member of type HashMap<String, u8>
, and so on.
I want to define a method that can access these HashMap
members and do generic actions on them that don't involve the value. For example, I want to count the number of keys, remove a key, check if a key exists, etc. I'm not sure how to implement this behavior.
The best way I had in mind so far is to define a trait that has a method that exposes the HashMap
and let each struct implement it. However I don't know how to write this trait and method in a way that "ignores" the value type. I tried using a wildcard (_
) but it doesn't work. How do I implement this?
Here is my code (which doesn't compile):
use std::collections::HashMap;
pub trait HashMapContainer {
fn get_hash_map(&self) -> HashMap<String, _>;
}
struct HashMapContainerImpl1 {
map: HashMap<String, String>,
}
impl HashMapContainerImpl1 {
pub fn new() -> HashMapContainerImpl1 {
HashMapContainerImpl1 {
map: HashMap::new(),
}
}
fn internal_logic_on_map(&mut self) {
//....
}
}
impl HashMapContainer for HashMapContainerImpl1 {
fn get_hash_map(&self) -> HashMap<String, _> {
self.map
}
}
struct HashMapContainerImpl2 {
map: HashMap<String, u8>,
}
impl HashMapContainerImpl2 {
pub fn new() -> HashMapContainerImpl2 {
HashMapContainerImpl2 {
map: HashMap::new(),
}
}
fn internal_logic_on_map(&mut self) {
//....
}
}
impl HashMapContainer for HashMapContainerImpl2 {
fn get_hash_map(&self) -> HashMap<String, _> {
self.map
}
}
fn do_generic_actions_on_map(hm_container: &HashMapContainer) {
println!("key count: {}", hm_container.get_hash_map().len());
println!(
"key esists? {}",
hm_container.get_hash_map().get("key1").is_some()
);
hm_container.get_hash_map().remove("key2");
}
fn main() {
let cont1 = HashMapContainerImpl1::new();
let cont2 = HashMapContainerImpl2::new();
do_generic_actions_on_map(cont1);
do_generic_actions_on_map(cont2);
}