Search code examples
multithreadingrustclonetraitslifetime

Cloning and moving traits


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!


Solution

  • 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.