Discussion:
[rust-dev] By-value variable captures landing soon
Patrick Walton
2014-08-19 20:05:27 UTC
Permalink
Hi everyone,

I've submitted a pull request to make captures in closures *by-value* by
default. Previously, they were all by-reference (except for `proc`).
This means that several code patterns will break. Mutating upvars is the
most common pattern:

let mut a = 10;
[ 1i, 2, 3 ].iter().map(|x| a += *x);

Change this code to:

let mut a = 10;
[ 1i, 2, 3 ].iter().map(ref |x| a += *x);

That is, add the `ref` keyword before the opening `|` of the closure.

As a simple measure to get your code up to date, you can simply prepend
`ref` en masse to your closures. This will allow you to opt into the old
semantics and will continue to work in the future.

This is a preparatory change for the move to unboxed closures. After
this, there should be no further changes necessary to get your closures
up to date; they should "just work" after closures become unboxed by
default. (However, the *types* of your closures may change in the future
once boxed closures are removed, so you may have to update
function/method/etc. signatures. But the closures themselves should not
need to change.)

Welcome to the brave new world!

Patrick
Patrick Walton
2014-08-19 20:07:37 UTC
Permalink
Post by Patrick Walton
I've submitted a pull request to make captures in closures *by-value* by
default.
Oh, here's the pull request:

https://github.com/rust-lang/rust/pull/16610

And here's the relevant RFC:

https://github.com/rust-lang/rfcs/blob/master/active/0038-capture-by-value.md

Related, the unboxed closures RFC:

https://github.com/rust-lang/rfcs/blob/master/active/0044-closures.md

Patrick
Evan G
2014-08-19 20:39:44 UTC
Permalink
Is there a way to capture some variables by-value, and others by-reference?
The 'ref' syntax you talked about seemed to be only for the whole argument
list, but I might have misunderstood.
Post by Patrick Walton
Post by Patrick Walton
I've submitted a pull request to make captures in closures *by-value* by
default.
https://github.com/rust-lang/rust/pull/16610
https://github.com/rust-lang/rfcs/blob/master/active/0038-
capture-by-value.md
https://github.com/rust-lang/rfcs/blob/master/active/0044-closures.md
Patrick
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140819/6785d00b/attachment.html>
Patrick Walton
2014-08-19 20:43:18 UTC
Permalink
Post by Evan G
Is there a way to capture some variables by-value, and others
by-reference? The 'ref' syntax you talked about seemed to be only for
the whole argument list, but I might have misunderstood.
If you need more fine-grained control, you can create references
explicitly outside the closure, and capture those by-value along with
the other values you'd like to capture by value.

Patrick
Evan G
2014-08-19 21:05:44 UTC
Permalink
That makes sense. Thanks.


On Tue, Aug 19, 2014 at 3:43 PM, Patrick Walton <pcwalton at mozilla.com>
Post by Patrick Walton
Post by Evan G
Is there a way to capture some variables by-value, and others
by-reference? The 'ref' syntax you talked about seemed to be only for
the whole argument list, but I might have misunderstood.
If you need more fine-grained control, you can create references
explicitly outside the closure, and capture those by-value along with the
other values you'd like to capture by value.
Patrick
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140819/9ecf1c45/attachment.html>
Daniel Micay
2014-08-19 20:43:31 UTC
Permalink
Post by Evan G
Is there a way to capture some variables by-value, and others
by-reference? The 'ref' syntax you talked about seemed to be only for
the whole argument list, but I might have misunderstood.
You can capture references by-value, because they're normal values. The
`ref` syntax is sugar for a common case.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140819/c6847a54/attachment.sig>
Loading...