Search code examples
clonerust

Omit double cloning value passed to function


I am writing a file watcher in Rust and I've encountered a problem with double cloning INotify to use it in spawned scope:

fn watch_file(watcher: INotify, path: &String) {
    let mut watcher = watcher.clone();
    let path = Path::new(path);
    let pusher = RedisPusher::new("redis://127.0.0.1/0", "arkona").unwrap();

    info!("Watching `{}`", path.as_str().unwrap());

    spawn(move || {
        let _ = watcher.watch(path, |_, file| {
            info!("Change in `{}`", file.path().as_str().unwrap());
            file.read_to_string().map(|content| pusher.push(content)).ok();
        });
    });
}

fn main() {
    let args = os::args();
    let watcher = INotify::init().unwrap();

    for path in args.tail().iter() {
        watch_file(watcher.clone(), path);
    }
}

I am still learning Rust and I cannot find any way to pass mutable watcher as value to this method. Is it the only (and idiomatic) way or is there any possibility to make it happen at most once?


Solution

  • On a side note, if you take ownership of a parameter (i.e. the parameter is not a reference), you don't have to declare the mutability in the function signature:

    fn add_thing(things: Vec<uint>) -> Vec<uint> {
        let mut things = things; // We own this, so we can make it mutable
        things.push(1);
        things
    }
    
    fn main() {
        let things = vec![3, 2];
        let changed = add_thing(things);
        println!("{}", changed);
    }