Reputation: 903
I have the following code:
pub trait Service {}
#[derive(Clone)]
pub struct Services {
providers: std::collections::HashMap<String, Box<dyn Service>>
}
which gives this error:
the trait `Clone` is not implemented for `dyn Service`
I also tried changing Service
to pub trait Service: Clone {}
but it gave me a different error that the trait cannot be made into an object because it is not object_safe (because it requires Self::Sized
.
playground - https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=eecca2b2bd82d4df4c34f44463594c58
Upvotes: 0
Views: 975
Reputation: 1235
You can add Clone in the definition of the type that is enclosed in Box.
Something like this
use std::collections::HashMap;
pub trait Service {}
#[derive(Clone)]
pub struct Services<T>
where
T: Service, //<--------
T: Clone //<----------- {
providers: std::collections::HashMap<String, Box<T>>
}
#[derive(Clone)]
pub struct A{}
impl Service for A {}
fn main()
{
let mut v: HashMap<String, Box<A>> = HashMap::new();
v.insert("test".to_string(), Box::new(A{}));
let o = Services{providers: v };
for (key, _) in o.providers.iter() {
println!("key: {} ", key);
}
}
The Sean version could be like this
use std::collections::HashMap;
use std::sync::Arc;
pub trait Service {}
#[derive(Clone)]
pub struct Services {
providers: Arc<std::collections::HashMap<String, Box<dyn Service>>>
}
#[derive(Clone)]
pub struct A{}
impl Service for A {}
#[derive(Clone)]
pub struct B{}
impl Service for B {}
fn main()
{
let mut objects: HashMap<String, Box<dyn Service>> = HashMap::new();
objects.insert("test".to_string(), Box::new(A{}));
objects.insert("test2".to_string(), Box::new(B{}));
let v = Arc::new(objects);
let o = Services{providers: v};
for (key, _) in o.providers.iter() {
println!("key: {} ", key);
}
}
Upvotes: 0
Reputation: 3042
I'm afraid that's not gonna happened, if you look at the definition of Clone, it is required to Sized, but a trait object is not sized, you can't implement Clone for it.
you can wrap the provide in the Rc or Arc like this
#[derive(Clone)]
pub struct Services {
providers: Arc<std::collections::HashMap<String, Box<dyn Service>>>
}
Upvotes: 2