@@ -4235,36 +4235,16 @@ fn main() {
4235
4235
}
4236
4236
```
4237
4237
4238
- ## Procs
4238
+ ## Moving closures
4239
4239
4240
- Rust has a second type of closure, called a ** proc** . Procs are created
4241
- with the ` proc ` keyword:
4242
-
4243
- ``` {rust}
4244
- let x = 5i;
4245
-
4246
- let p = proc() { x * x };
4247
- println!("{}", p()); // prints 25
4248
- ```
4249
-
4250
- There is a big difference between procs and closures: procs may only be called once. This
4251
- will error when we try to compile:
4252
-
4253
- ``` {rust,ignore}
4254
- let x = 5i;
4255
-
4256
- let p = proc() { x * x };
4257
- println!("{}", p());
4258
- println!("{}", p()); // error: use of moved value `p`
4259
- ```
4260
-
4261
- This restriction is important. Procs are allowed to consume values that they
4262
- capture, and thus have to be restricted to being called once for soundness
4263
- reasons: any value consumed would be invalid on a second call.
4264
-
4265
- Procs are most useful with Rust's concurrency features, and so we'll just leave
4266
- it at this for now. We'll talk about them more in the "Tasks" section of the
4267
- guide.
4240
+ Rust has a second type of closure, called a ** moving closure** . Moving
4241
+ closures are indicated using the ` move ` keyword (e.g., `move || x *
4242
+ x`). The difference between a moving closure and an ordinary closure
4243
+ is that a moving closure always takes ownership of all variables that
4244
+ it uses. Ordinary closures, in contrast, just create a reference into
4245
+ the enclosing stack frame. Moving closures are most useful with Rust's
4246
+ concurrency features, and so we'll just leave it at this for
4247
+ now. We'll talk about them more in the "Tasks" section of the guide.
4268
4248
4269
4249
## Accepting closures as arguments
4270
4250
@@ -5231,28 +5211,30 @@ concurrency libraries can be written for Rust to help in specific scenarios.
5231
5211
Here's an example of creating a task:
5232
5212
5233
5213
``` {rust}
5234
- spawn(proc() {
5214
+ spawn(move || {
5235
5215
println!("Hello from a task!");
5236
5216
});
5237
5217
```
5238
5218
5239
- The ` spawn ` function takes a proc as an argument, and runs that proc in a new
5240
- task. A proc takes ownership of its entire environment, and so any variables
5241
- that you use inside the proc will not be usable afterward:
5219
+ The ` spawn ` function takes a closure as an argument, and runs that
5220
+ closure in a new task. Typically, you will want to use a moving
5221
+ closure, so that the closure takes ownership of any variables that it
5222
+ touches. This implies that those variables are not usable from the
5223
+ parent task after the child task is spawned:
5242
5224
5243
5225
``` {rust,ignore}
5244
5226
let mut x = vec![1i, 2i, 3i];
5245
5227
5246
- spawn(proc() {
5228
+ spawn(move || {
5247
5229
println!("The value of x[0] is: {}", x[0]);
5248
5230
});
5249
5231
5250
5232
println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x`
5251
5233
```
5252
5234
5253
- ` x ` is now owned by the proc , and so we can't use it anymore. Many other
5254
- languages would let us do this, but it's not safe to do so. Rust's borrow
5255
- checker catches the error.
5235
+ ` x ` is now owned by the closure , and so we can't use it anymore. Many
5236
+ other languages would let us do this, but it's not safe to do
5237
+ so. Rust's borrow checker catches the error.
5256
5238
5257
5239
If tasks were only able to capture these values, they wouldn't be very useful.
5258
5240
Luckily, tasks can communicate with each other through ** channel** s. Channels
@@ -5261,7 +5243,7 @@ work like this:
5261
5243
``` {rust}
5262
5244
let (tx, rx) = channel();
5263
5245
5264
- spawn(proc() {
5246
+ spawn(move || {
5265
5247
tx.send("Hello from a task!".to_string());
5266
5248
});
5267
5249
@@ -5281,7 +5263,7 @@ If you want to send messages to the task as well, create two channels!
5281
5263
let (tx1, rx1) = channel();
5282
5264
let (tx2, rx2) = channel();
5283
5265
5284
- spawn(proc() {
5266
+ spawn(move || {
5285
5267
tx1.send("Hello from a task!".to_string());
5286
5268
let message = rx2.recv();
5287
5269
println!("{}", message);
@@ -5293,8 +5275,9 @@ println!("{}", message);
5293
5275
tx2.send("Goodbye from main!".to_string());
5294
5276
```
5295
5277
5296
- The proc has one sending end and one receiving end, and the main task has one
5297
- of each as well. Now they can talk back and forth in whatever way they wish.
5278
+ The closure has one sending end and one receiving end, and the main
5279
+ task has one of each as well. Now they can talk back and forth in
5280
+ whatever way they wish.
5298
5281
5299
5282
Notice as well that because ` Sender ` and ` Receiver ` are generic, while you can
5300
5283
pass any kind of information through the channel, the ends are strongly typed.
@@ -5310,34 +5293,34 @@ a useful thing to use:
5310
5293
``` {rust}
5311
5294
use std::sync::Future;
5312
5295
5313
- let mut delayed_value = Future::spawn(proc() {
5296
+ let mut delayed_value = Future::spawn(move || {
5314
5297
// just return anything for examples' sake
5315
5298
5316
5299
12345i
5317
5300
});
5318
5301
println!("value = {}", delayed_value.get());
5319
5302
```
5320
5303
5321
- Calling ` Future::spawn ` works just like ` spawn() ` : it takes a proc. In this
5322
- case, though, you don't need to mess with the channel: just have the proc
5323
- return the value.
5304
+ Calling ` Future::spawn ` works just like ` spawn() ` : it takes a
5305
+ closure. In this case, though, you don't need to mess with the
5306
+ channel: just have the closure return the value.
5324
5307
5325
5308
` Future::spawn ` will return a value which we can bind with ` let ` . It needs
5326
5309
to be mutable, because once the value is computed, it saves a copy of the
5327
5310
value, and if it were immutable, it couldn't update itself.
5328
5311
5329
- The proc will go on processing in the background, and when we need the final
5330
- value, we can call ` get() ` on it. This will block until the result is done,
5331
- but if it's finished computing in the background, we'll just get the value
5332
- immediately.
5312
+ The future will go on processing in the background, and when we need
5313
+ the final value, we can call ` get() ` on it. This will block until the
5314
+ result is done, but if it's finished computing in the background,
5315
+ we'll just get the value immediately.
5333
5316
5334
5317
## Success and failure
5335
5318
5336
5319
Tasks don't always succeed, they can also panic. A task that wishes to panic
5337
5320
can call the ` panic! ` macro, passing a message:
5338
5321
5339
5322
``` {rust}
5340
- spawn(proc() {
5323
+ spawn(move || {
5341
5324
panic!("Nope.");
5342
5325
});
5343
5326
```
@@ -5349,7 +5332,7 @@ notify other tasks that it has panicked. We can do this with `task::try`:
5349
5332
use std::task;
5350
5333
use std::rand;
5351
5334
5352
- let result = task::try(proc() {
5335
+ let result = task::try(move || {
5353
5336
if rand::random() {
5354
5337
println!("OK");
5355
5338
} else {
0 commit comments