Reputation: 3196
I'd like to be able to move a cloned version of an object that implements trait Foo
into various threads. I cannot seem to figure out how this is achieved. I've tried cloning and moving a Box<Foo>
and specifying the parameter as a generic, but cannot seem make the compiler happy.
My first attempt:
use std::thread;
pub trait Foo {
fn bar();
}
pub struct Thing;
impl Thing {
pub fn something(handler: Box<Foo>) {
let handler_1 = handler.clone();
thread::spawn(move || {
Thing::another_thread(handler_1)
});
}
fn another_thread(handler: Box<Foo>) { }
}
Resulted in the following errors:
error: no method named clone found for type Box<Foo + 'static> in the current scope
error: the trait core::marker::Send is not implemented for the type Foo [E0277]
Next I tried writing it as a generic parameter...
use std::thread;
pub trait Foo {
fn bar();
}
pub struct Thing;
impl Thing {
pub fn something<T: Foo + Clone + Send>(handler: T) {
let handler_1 = handler.clone();
thread::spawn(move || {
Thing::another_thread(handler_1)
});
}
fn another_thread<T: Foo>(handler: T) { }
}
Received the following error:
error: the parameter type T may not live long enough [E0310]
help: consider adding an explicit lifetime bound T: 'static...
Now we've reached the point where I'm lost and I start poking <'a>
into every crevice hoping it solves the problem. But, unfortunately, I have no idea what the syntax is for what I'm trying to achieve. Thanks in advance for any help!
Upvotes: 0
Views: 70
Reputation: 430821
consider adding an explicit lifetime bound
T: 'static
...
That looks like this:
pub fn something<T: 'static + Foo + Clone + Send>(handler: T)
which compiles.
In case you are unfamiliar with this syntax, it means that whatever concrete type of T
is picked, it must outlive the 'static
lifetime. This includes any interior references / lifetimes the concrete type may have.
Upvotes: 1