Modify values in function that run several times internally

I would like to modify the value inside the function that call function several times internally, how can I achieve it?

It works fine if I run Function once, (without Copy)

But, if I would like to run Function several times, I need Copy on Function
Then, errors occur,

note: std::marker::Copy is implemented for &u32, but not for &mut u32

I have no idea how to go any further.

#![allow(unused)]

fn print_string<F>(f: F)
where
    F: FnOnce() + Copy,
{
    for i in 0..2 {
        f();
    }
    
    // Wwork fine if we run F once
    // f();
}
fn main() {
    // some others value that initialize here
    let mut call_func_time: u32 = 0;

    print_string(|| {
        // modify the value, this function will call several times, so we can't initialize the values here.
        // and the value will only be modified by this function called.
        call_func_time += 1;
        println!("{}", format!("{}", call_func_time))
    });
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=306aff828fdb99d5e1b46094c9d40a3e

FnOnce is for one-time-use function, hence its name contains Once. I've modified your code to make it work.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f13ff11870710c708fd48c14faf9fcb0

FnOnce() + Copy can be seen as they can be called multiple times, but actually the value f is copied out implicitly whenever it's called, since it's Copy. I'd highly recommend to read the Copy docs carefully.

https://doc.rust-lang.org/stable/std/marker/trait.Copy.html

And also the book has a chapter for those Fn* traits. It would be worth to read again this chapter.

https://doc.rust-lang.org/stable/book/ch13-01-closures.html#storing-closures-using-generic-parameters-and-the-fn-traits

1 Like