Search code examples
rustownership

Map without side-effects? A map that takes ownership (and not a mutable reference) on insert?


Is there a data structure in Rust that would have the following kind of function signatures?

impl<K, V> Map<K,V> {
  fn insert(self, key: K, value: V) -> Self
}

i.e. It does not take a mutable reference to itself, and instead takes ownership (like a builder pattern).

Inspiration mostly comes from something like a Haskell Map


Solution

  • As already mentioned in the comments, you can create a new type that internally uses std::collections::HashMap. Here is a basic example:

    use std::collections::HashMap;
    use std::ops::Deref;
    
    #[derive(Debug)]
    struct Map<K, V>(HashMap<K, V>);
    
    impl<K, V> Deref for Map<K, V> {
        type Target = HashMap<K, V>;
    
        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }
    
    impl<K, V> Map<K, V>
    where
        K: std::hash::Hash + Eq,
    {
        pub fn new() -> Self {
            Map(HashMap::new())
        }
    
        pub fn insert(mut self, key: K, value: V) -> Self {
            self.0.insert(key, value);
    
            self
        }
    }
    
    fn main() {
        let map = Map::new()
            .insert("a", "A")
            .insert("b", "B")
            .insert("c", "C");
    
        println!("{:?}", map);
        println!("{:?}", *map);
    }
    
    

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=61eb137defe2aceef7e748f52c0037b7