2

I have HashMap with custom hasher. Items of this HashMap without implemented trait Clone (it's a trait), but there is function to clone items like this:

use std::collections::HashMap;
use std::hash::BuildHasherDefault;

use fnv::FnvHasher;

trait Item {
    fn get_id(&self) -> i32;
    fn cloned(&self) -> Box<Item>;
}

#[derive(Clone)]
struct ItemImpl {
    id: i32,
    foo: i32
}

impl Item for ItemImpl {
    fn get_id(&self) -> i32 { self.id }
    fn cloned(&self) -> Box<Item> { Box::new(self.clone()) }
}

fn main() {
    let hash_map = HashMap::<i32, Box<Item>, BuildHasherDefault<FnvHasher>>::default();
}

How I could clone hash_map shortly (in code) and efficiently (without creating a temporary collection)?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
xilec
  • 95
  • 1
  • 8
  • I don't think you can use a `HashMap::` at all, the value should be a Sized type, but a trait is Unsized. – kennytm Aug 24 '16 at 10:21
  • Can you just implement `Clone`? – Chris Emerson Aug 24 '16 at 10:28
  • 1
    It's not clear what this question is asking. Could you say more about what problem you're trying to solve? – BurntSushi5 Aug 24 '16 at 10:46
  • @kennytm, It's my misstype. Should be Box – xilec Aug 24 '16 at 11:24
  • @ChrisEmerson, I wish, but it beaks [object safety](https://doc.rust-lang.org/book/trait-objects.html#object-safety) and other parts of code – xilec Aug 24 '16 at 11:28
  • @BurntSushi5, I just wish clone specified HashMap, but I can't implement trait `Clone` for my trait `Item`, thus I can't use method `HashMap::clone()` – xilec Aug 24 '16 at 11:43
  • Can you use a wrapper struct here and implement `Clone` for that? – Chris Emerson Aug 24 '16 at 11:51
  • Yes, I can. But changing definition of `HashMap` just for cloning, it seems a bit strange to me. May be there is another solution without changing other code that work with this `HashMap`? – xilec Aug 24 '16 at 12:36

1 Answers1

5

You can implement Clone for the boxed trait object itself:

impl Clone for Box<Item> {
    fn clone(&self) -> Self {
        self.cloned()
    }
}

Now you may clone the HashMap. Note that the custom hasher has nothing to do with the problem.

See also

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366