Lambda expression lifetime in rust

If I have a function that returns a function:

fn<'r, T> ( p : T ) -> (&'r fn(&'r str) -> ~[(T,int)]) { return |s| ~[(p, 0)] } 

However, this does not seem to work, I get the following (somewhat tautological) error:

 playground.rs:10:8: 10:29 error: cannot infer an appropriate lifetime due to conflicting requirements playground.rs:10 return |s| ~[(p, 0i)] ^~~~~~~~~~~~~~~~~~~~~ playground.rs:9:70: 11:5 note: first, the lifetime cannot outlive the block at 9:70... playground.rs:9 pub fn result<'r, T>( p : T ) -> (&'r fn(&'r str) -> ~[(T, int)] ){ playground.rs:10 return |s| ~[(p, 0i)] playground.rs:11 } playground.rs:10:8: 10:29 note: ...due to the following expression playground.rs:10 return |s| ~[(p, 0i)] ^~~~~~~~~~~~~~~~~~~~~ playground.rs:9:70: 11:5 note: but, the lifetime must be valid for the lifetime &'r as defined on the block at 9:70... playground.rs:9 pub fn result<'r, T>( p : T ) -> (&'r fn(&'r str) -> ~[(T, int)] ){ playground.rs:10 return |s| ~[(p, 0i)] playground.rs:11 } playground.rs:10:8: 10:29 note: ...due to the following expression playground.rs:10 return |s| ~[(p, 0i)] ^~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error 

I believe that this suggests that the lifetime of the returned function and the returned value do not match. However, I do not know how to annotate a lambda with a lifelong life to do this job.

+7
lambda rust lifetime
source share
1 answer

Thus, this is a common mistake in rust, considering that the parameters of the lifetime affect the lifetime.

They don’t do this, they only let the compiler know that the link returned by the function takes some time. In any case, that would be true, but now the compiler is also aware of this and can provide more secure code. This is due to the fact that Rust conducts local analysis (while looking at one function).

In this case, you create a stack close. As the name implies, a stack closure is created on the stack and you then push it back onto the stack. This is similar to this C code:

 int *foo() { int a = 5; return &a; } 

Obviously, a pointer (or "link") to a invalid the moment you return. This is what prevents rust.

In this case, the lifetime of the stack closure continues for the duration of the function, but the lifetime parameter requires it to last longer than this (although there is nothing to say how long it is for sure), therefore, a mismatch error.

The basic rule of thumb is that if you have lifetime parameters for a function, you need each parameter at a position in the argument list and return type, otherwise you probably have something wrong.

If you really want to return a closure, then you should use the heap closure, ~fn (&str) -> ~[(T, int)] , since it is allocated on the heap and can be transferred more freely (although still not copied).

+12
source share

All Articles