for i in 0..3 {
thread::spawn(move || {
data[i] += 1;
});
}
What is the 'move' thing here before the || for i in 0..3 {
thread::spawn(move || {
data[i] += 1;
});
}
What is the 'move' thing here before the || var closures = [];
for (var i=0;i<5;i++) {
closures.push(function() {
console.log(i);
});
}
The code above will result in incorrect results: 5, 5, 5, 5, 5. Because you're capturing `i` as a reference.To avoid this, JS devs typically do this:
closures.push((function(i) {
return function() {
console.log(i);
};
})(i));
Or, if you can afford the ES6 support: for (let i=0;i<5;i++) {
/* `let`-scoped `i`s are created individually at each iteration, so it is safe to capture them by references. */
}
Rust supports this pattern by a built-in syntax. That's what `move` means. If you prepend the `move` keyword before the closure, the variables will be captured by values, not references.Wouldn't it have been a better approach to add some sort of demarkation, such as i* or i^ (or whatever) to indicate this?
Just curious.
That's the path C++ took[0], the Rust people thought it had too much syntactic and semantic overhead, and that having just "move" and "referring" closures would be much simpler. If you want to mix them up, it's easy enough to create references outside the closure (and capture them by value with a move closure)
[0] http://en.cppreference.com/w/cpp/language/lambda#Lambda_capt...
In particular, don't miss this post: https://www.reddit.com/r/rust/comments/46w4g4/what_is_rusts_...
for (var i = 0; i < 5; i++) {
let i_ = i;
/* use i_ in the closure */
}
In your ES6 solution if you e.g. increment "i" inside the loop after the closure the closure will see the mutation!The real cause of confusion is mutation and javascript's scoping rules.
However, in Rust, you get an error if you accidentally capture by reference in the closure passed to `thread::spawn` so it's not as hard to get right as it is in JS.
for(let i = 0; i < 5; i++) {
// no hacks needed if you don't use ES5 var
}That said, you're right that saying "copy" is misleading, for this reason. But moves _are_ a kind of copy.