EDIT: I replaced int with i32 because int now deprecated. It has been replaced by isize , but this is probably not the right type.
The compiler does not complain about the close parameter; he complains about the closure itself. You need to specify the service life for closing.
fn bar<'a>(x: i32) -> (|i32|:'a -> i32) { |n: i32| -> i32 { if n < x { return n } x } }
But this does not work:
<anon>:13:16: 13:17 error: captured variable `x` does not outlive the enclosing closure <anon>:13 if n < x { return n } ^ <anon>:11:41: 17:2 note: captured variable is valid for the block at 11:40 <anon>:11 fn bar<'a>(x: i32) -> (|i32|:'a -> i32) { <anon>:12 |n: i32| -> i32 { <anon>:13 if n < x { return n } <anon>:14 <anon>:15 x <anon>:16 } ... <anon>:11:41: 17:2 note: closure is valid for the lifetime 'a as defined on the block at 11:40 <anon>:11 fn bar<'a>(x: i32) -> (|i32|:'a -> i32) { <anon>:12 |n: i32| -> i32 { <anon>:13 if n < x { return n } <anon>:14 <anon>:15 x <anon>:16 } ...
This is because a closure tries to capture x by reference, but a closure survives x , which is illegal (it would also be illegal to return a reference to x ).
Try using proc . A proc captures values by moving.
EDIT: proc been removed from the language since this answer was originally recorded.
fn main() { let foo = bar(8); println!("Trying `foo` with 4: {:d}", foo(4)); println!("Trying `foo` with 8: {:d}", foo(8)); println!("Trying `foo` with 13: {:d}", foo(13)); }
Unfortunately, this does not work either.
<anon>:5:43: 5:46 error: use of moved value: `foo` <anon>:5 println!("Trying `foo` with 8: {:d}", foo(8)); ^~~ note: in expansion of format_args! <std macros>:2:23: 2:77 note: expansion site <std macros>:1:1: 3:2 note: in expansion of println! <anon>:5:5: 5:51 note: expansion site <anon>:4:43: 4:46 note: `foo` moved here because it has type `proc(i32) -> i32`, which is non-copyable (perhaps you meant to use clone()?) <anon>:4 println!("Trying `foo` with 4: {:d}", foo(4)); ^~~
You can call proc once. The call requires closure.
The correct solution now is to use the “unpacked” closures:
fn main() { let foo = bar(8); println!("Trying `foo` with 4: {}", foo(4)); println!("Trying `foo` with 8: {}", foo(8)); println!("Trying `foo` with 13: {}", foo(13)); }
Output:
Trying `foo` with 4: 4 Trying `foo` with 8: 8 Trying `foo` with 13: 8