1

I am trying to write a section of code that does a web request every few seconds and updates a struct in rust. I have so far tried using a thread to accomplish this task however I am having some real trouble moving variables into the thread and assigning the results of the web request to a struct once it completes.

I have provided a small code sample below that doesn't include a web request but does demonstrate the problem I am having moving variables around.

Code:

use std::thread;

#[derive(Debug, Clone)]
struct input_holder {
    i : String,
}

fn main() {
    // pass this string into the thread loop.
    let input = String::from("This is a string");
    let input_loop = input.clone();
    
    //assign the output of the method to this struct.
    let ih = input_holder {
        i : input
    };

    thread::spawn(|| {
        let runtime = tokio::runtime::Runtime::new().unwrap();
        loop {
            let _ = runtime.block_on(runtime.spawn(async move {
                let _new_input = match update_string(input_loop.clone(), ih.clone()){
                    Some(ni) => ni,
                    None => String::from("None")
                };
            }));
        }
    });
}

//This is where I would do the web request. I can test this method outside of the thread and it works as expected.
pub fn update_string(_input: String, mut ih: input_holder) -> Option<String> {
    ih.i = String::from("This is an updated string");
    Some(String::from("This is an updated string"))
}

Below is the error message I am running into:

error[E0382]: use of moved value: `ih`
  --> src/main.rs:64:63
   |
64 |               let _ = runtime.block_on(runtime.spawn(async move {
   |  _______________________________________________________________^
65 | |                 let _new_input = match update_string(input_loop.clone(), ih.clone()){
   | |                                                                          -- use occurs due to use in generator
66 | |                     Some(ni) => ni,
67 | |                     None => String::from("None")
68 | |                 };
69 | |             }));
   | |_____________^ value moved here, in previous iteration of loop
   |
   = note: move occurs because `ih` has type `input_holder`, which does not implement the `Copy` trait

There doesn't seem to be anyway for me to pass ih that I am aware of, I don't know what use occurs due to use in generator means and Google does not seem to have much on this error (there are a bunch of options for move occurs due to use in generator but nothing for this error).

I have tried cloning and not cloning, borrowing, removing the move from the loop (I should note here I can't implement the copy trait on the struct). How are you supposed to get variables in and out of a thread loop like this?

I think I might not be understanding something about how you are supposed to move variables around in rust because in general I find myself needing to make lots and lots of copies of any value I plan to pass between methods.

cafce25
  • 15,907
  • 4
  • 25
  • 31
John554
  • 145
  • 1
  • 7
  • Rel: [What does `move occurs due to use in generator` error mean?](https://stackoverflow.com/questions/68462733/what-does-move-occurs-due-to-use-in-generator-error-mean-in-rust) – cafce25 Jan 22 '23 at 23:43
  • Also Rel: [Need holistic explanation about Rust's cell and reference counted types](https://stackoverflow.com/questions/45674479/need-holistic-explanation-about-rusts-cell-and-reference-counted-types) – cafce25 Jan 23 '23 at 00:37

0 Answers0