Things you can’t do in Rust: copy closures

Written by andrew_lucker | Published 2017/12/04
Tech Story Tags: programming | rust | computer-science | software-development | functional-programming

TLDRvia the TL;DR App

I love Rust and want it to be better. The dev teams know about all issues presented. I just want to generate discussion and enthusiasm for making a good language better.

fn main() {// Many closures can now be passed by-value to multiple functions:fn call<F: FnOnce()>(f: F) { f() }let hello = || println!("Hello, world!");call(hello);call(hello);

// Many `Iterator` combinators are now `Copy`/`Clone`:let x = (1..100).map(|x| x * 5);let y = x.map(|x| x - 3); // moves `x` by `Copy`inglet _ = x.chain(y); // moves `x` againlet _ = x.cycle(); // `.cycle()` is only possible when `Self: Clone`

// Closures which reference data mutably are not `Copy`/`Clone`:let mut x = 0;let incr_x = || x += 1;call(incr_x);call(incr_x); // ERROR: `incr_x` moved in the call above.

// `move` closures implement `Clone`/`Copy` if the values they capture// implement `Clone`/`Copy`:let mut x = 0;let print_incr = move || { println!("{}", x); x += 1; };

fn call_three_times<F: FnMut()>(mut f: F) {for i in 0..3 {f();}}call_three_times(print_incr); // prints "0", "1", "2"call_three_times(print_incr); // prints "0", "1", "2"}

Result (compile time error):

error[E0277]: the trait bound `[[email protected]:9:24: 9:33]: std::clone::Clone` is not satisfied|12 **| ** let _ = x.cycle(); // `.cycle()` is only possible when `Self: Clone`**| ** ^^^^^ the trait `std::clone::Clone` is not implemented for `[[email protected]:9:24: 9:33]`|= note: required because of the requirements on the impl of `std::clone::Clone` for `std::iter::Map<std::ops::Range<{integer}>, [[email protected]:9:24: 9:33]>`

error: aborting due to previous error(s)

To be fair this feature is partially implemented. To implement Copy, the compiler needs to be careful about lifetimes and mutability, so this is not a simple feature to add. Many common cases have been covered so far, but as the RFC (2132) example illustrates, there is still a long way to go. For now this is yet another wart on closures.


Published by HackerNoon on 2017/12/04