Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inability to capture by Clone prevents some closures from being pure functions that otherwise could/should be. Any workaround?

Consider the following:


    use std::ops::Fn;
    
    fn require_picky_callback( cb : impl Fn() -> () + 'static) { }
    
    fn main() {
        let s = String::from("Rust");
        ...
        let s_copy = s.clone();
        let cb = move || {
            s_copy;
        };
        require_picky_callback(cb);
    
    }

If String in this example were replaced with a Copy-able type such as int, this example would compile. Unfortunately since capture by Clone is not possible, the only workaround is to create a copy outside the closure and move it in, but then the closure is no longer a pure function Fn, and instead a FnOnce. Is there any workaround such that my closure remains a Fn but also captures the String? This seems like it should be possible in principal.

Note that this RFC where the inability to clone into closure issue is discussed has a similar example, but less restrictive since the thread::spawn function does not require Fn

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Easy, just make a copy for each invocation and thus don’t move the String out of the closure:

fn require_picky_callback(_cb: impl Fn() -> () + 'static) {}

fn main() {
    let s = String::from("Rust");
    let cb = move || {
        let s = s.clone();
        drop(s);
    };
    require_picky_callback(cb);
}

This works because while s is captured by the closure, but because clone only requires a reference it’s never moved out of.

The drop is only there to show we can do anything we want with the new s it’s not required at all.

Playground link

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading