5
votes

I am trying to use a method in a thread in Rust, but I get the following error message

:21:10: 21:23 error: the type [closure@<anon>:21:24: 23:14 tx:std::sync::mpsc::Sender<i32>, self:&MyStruct, adder:i32, a:i32] does not fulfill the required lifetime :21
thread::spawn(move || { ^~~~~~~~~~~~~ :18:9: 24:10 note: in this expansion of for loop expansion note: type must outlive the static lifetime error: aborting due to previous error

This is the example code:

use std::thread;
use std::sync::mpsc;

struct MyStruct {
    field: i32
}

impl MyStruct {
    fn my_fn(&self, adder1: i32, adder2: i32) -> i32 {
        self.field + adder1 + adder2
    }

    fn threade_test(&self) {
        let (tx, rx) = mpsc::channel();
        let adder = 1;
        let lst_adder = vec!(2, 2, 2);

        for a in lst_adder {
            let tx = tx.clone();

            thread::spawn(move || {
                let _ = tx.send(self.my_fn(adder, a));
            });
        }

        println!("{}", rx.recv().unwrap());
    }
}

fn main() {
    let ms = MyStruct{field: 42};
    ms.threade_test();
}

Test it on the Rust Playground.

1
Have you read other questions with the same (or similar) error? A quick search found this one and this one.Shepmaster
Also, please take the time to create an MCVE of your problem. This makes it easier for you to understand where the problem is, and makes it easier for people to answer your question. In this case, this version is smaller.Shepmaster
@Shepmaster none of the two links solved my problem.Moebius

1 Answers

8
votes

The problem is that every variable moved to the thread must have the lifetime 'static. i.e. threads can't reference values which are not owned by the thread.

In this case the problem is that self is a reference to an instance of MyStruct.

To solve it, remove every reference and clone the structure before sending it to the thread.

use std::thread;
use std::sync::mpsc;

#[derive(Clone)]
struct MyStruct {
    field: i32
}

impl MyStruct {
    fn my_fn(&self, adder1: i32, adder2: i32) -> i32 {
        self.field + adder1 + adder2
    }

    fn threade_test(&self) {
        let (tx, rx) = mpsc::channel();
        let adder = 1;
        let lst_adder = vec!(2, 2, 2);

        for a in lst_adder {
            let tx = tx.clone();

            let self_clone = self.clone();
            thread::spawn(move || {
                let _ = tx.send(self_clone.my_fn(adder, a));
            });
        }

        println!("{}", rx.recv().unwrap());
    }
}

fn main() {
    let ms = MyStruct{field: 42};
    ms.threade_test();
}