@@ -324,37 +324,34 @@ first, it may seem strange, but we’ll figure it out. Here’s how you’d prob
324
324
try to return a closure from a function:
325
325
326
326
``` rust,ignore
327
- fn factory() -> (Fn(i32) -> Vec< i32> ) {
328
- let vec = vec![1, 2, 3] ;
327
+ fn factory() -> (Fn(i32) -> i32) {
328
+ let num = 5 ;
329
329
330
- |n| vec.push(n)
330
+ |x| x + num
331
331
}
332
332
333
333
let f = factory();
334
334
335
- let answer = f(4 );
336
- assert_eq!(vec![1, 2, 3, 4] , answer);
335
+ let answer = f(1 );
336
+ assert_eq!(6 , answer);
337
337
```
338
338
339
339
This gives us these long, related errors:
340
340
341
341
``` text
342
342
error: the trait `core::marker::Sized` is not implemented for the type
343
- `core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
344
- f = factory();
345
- ^
346
- note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a
347
- constant size known at compile-time
348
- f = factory();
349
- ^
350
- error: the trait `core::marker::Sized` is not implemented for the type
351
- `core::ops::Fn(i32) -> collections::vec::Vec<i32>` [E0277]
352
- factory() -> (Fn(i32) -> Vec<i32>) {
353
- ^~~~~~~~~~~~~~~~~~~~~
354
- note: `core::ops::Fn(i32) -> collections::vec::Vec<i32>` does not have a constant size known at compile-time
355
- factory() -> (Fn(i32) -> Vec<i32>) {
356
- ^~~~~~~~~~~~~~~~~~~~~
357
-
343
+ `core::ops::Fn(i32) -> i32` [E0277]
344
+ fn factory() -> (Fn(i32) -> i32) {
345
+ ^~~~~~~~~~~~~~~~
346
+ note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time
347
+ fn factory() -> (Fn(i32) -> i32) {
348
+ ^~~~~~~~~~~~~~~~
349
+ error: the trait `core::marker::Sized` is not implemented for the type `core::ops::Fn(i32) -> i32` [E0277]
350
+ let f = factory();
351
+ ^
352
+ note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time
353
+ let f = factory();
354
+ ^
358
355
```
359
356
360
357
In order to return something from a function, Rust needs to know what
@@ -364,16 +361,16 @@ way to give something a size is to take a reference to it, as references
364
361
have a known size. So we’d write this:
365
362
366
363
``` rust,ignore
367
- fn factory() -> &(Fn(i32) -> Vec< i32> ) {
368
- let vec = vec![1, 2, 3] ;
364
+ fn factory() -> &(Fn(i32) -> i32) {
365
+ let num = 5 ;
369
366
370
- |n| vec.push(n)
367
+ |x| x + num
371
368
}
372
369
373
370
let f = factory();
374
371
375
- let answer = f(4 );
376
- assert_eq!(vec![1, 2, 3, 4] , answer);
372
+ let answer = f(1 );
373
+ assert_eq!(6 , answer);
377
374
```
378
375
379
376
But we get another error:
@@ -448,7 +445,8 @@ assert_eq!(6, answer);
448
445
We use a trait object, by ` Box ` ing up the ` Fn ` . There’s just one last problem:
449
446
450
447
``` text
451
- error: `num` does not live long enough
448
+ error: closure may outlive the current function, but it borrows `num`,
449
+ which is owned by the current function [E0373]
452
450
Box::new(|x| x + num)
453
451
^~~~~~~~~~~
454
452
```
0 commit comments