Clone when moving into a closure

quick question,

fn main() {
    let s1 = String::from("hello");
    let closure = move || {
        let s2 = s1.clone();
    };
    println!("{}", s1);
}

This will give an error bcs the s1 ownership goes to the closure. One way we can fix this is by cloning s1 before it enters the closure. But this will become hard to read if I got many closure that needs that data.

My question, is there any work around to make the cloning process happens inside the closure? or is there something like clone || {} available?

Why don't you just remive move kw?

fn main() {
    let s1 = String::from("hello");
    let closure = || {
        let s2 = s1.clone();
        println!("{}", s2);
    };
    closure();
    println!("{}", s1);
}
1 Like

Removing move can cause other problems:

fn consume(s: String) {
    println!("{s}");
}

fn main() {
    let s1 = String::from("hello");
    let closure = || {
        let s2 = s1.clone();
        consume(s2);
    };
    consume(s1);
    closure();
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0505]: cannot move out of `s1` because it is borrowed
  --> src/main.rs:11:13
   |
7  |     let closure = || {
   |                   -- borrow of `s1` occurs here
8  |         let s2 = s1.clone();
   |                  -- borrow occurs due to use in closure
...
11 |     consume(s1);
   |             ^^ move out of `s1` occurs here
12 |     closure();
   |     ------- borrow later used here

For more information about this error, try `rustc --explain E0505`.
error: could not compile `playground` due to previous error

Clone first, and only move the cloned value into the closure.

1 Like

Yes, but this was what the OP found a bit troublesome, syntax-wise:

There is not, modulo macros to emulate it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.