Would you have any idea about below issue with closure?
fn f1(w: &str) -> &str {
w
}
fn main() {
let hello = "hello";
let f2 = |w: &str| -> &str {
w
};
assert_eq!(f2(hello), hello);
}
failed with:
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/main.rs:9:9
|
8 | let f2 = |w: &str| {
| - - return type of closure is &'2 str
| |
| let's call the lifetime of this reference `'1`
9 | w
| ^ returning this value requires that `'1` must outlive `'2`
error: could not compile `playground` (bin "playground") due to 1 previous error
while it works when it is defined as function: Rust Playground
fn f1(w: &str) -> &str {
w
}
fn main() {
let hello = "hello";
assert_eq!(f1(hello), hello);
}
Also note that you can sometimes get better results when you do not annotate the closure params and return value. IME the compiler is better at inferring the types of closures. So this works on stable:
The stable general solution to this problem is to pass the closure to a function whose signature constrains the signature of the closure:
fn same_lt_in_and_out<T: ?Sized, F>(f: F) -> F
where
F: for<'a> Fn(&'a T) -> &'a T,
{
f
}
let f2 = same_lt_in_and_out(|w: &str| -> &str { w });
The Rust compiler can be understood as essentially having a special rule that says "when a closure is passed to a function with a Fn* bound, use that bound as the closure's signature”. This is why this problem doesn’t come up in common uses of closures like Iterator::map(): most of the time, the closures do get passed directly to functions for use as callbacks of some sort.