@@ -319,6 +319,53 @@ assert_eq!(3, answer);
319319Now we take a trait object, a ` &Fn ` . And we have to make a reference
320320to our closure when we pass it to ` call_with_one ` , so we use ` &|| ` .
321321
322+ A quick note about closures that use explicit lifetimes. Sometimes you might have a closure
323+ that takes a reference like so:
324+
325+ ```
326+ fn call_with_ref<F>(some_closure:F) -> i32
327+ where F: Fn(&i32) -> i32 {
328+
329+ let mut value = 0;
330+ some_closure(&value)
331+ }
332+ ```
333+
334+ Normally you can specify the lifetime of the parameter to our closure. We
335+ could annotate it on the function declaration:
336+
337+ ``` ignore
338+ fn call_with_ref<'a, F>(some_closure:F) -> i32
339+ where F: Fn(&'a 32) -> i32 {
340+ ```
341+
342+ However this presents a problem with in our case. When you specify the explict
343+ lifetime on a function it binds that lifetime to the * entire* scope of the function
344+ instead of just the invocation scope of our closure. This means that the borrow checker
345+ will see a mutable reference in the same lifetime as our immutable reference and fail
346+ to compile.
347+
348+ In order to say that we only need the lifetime to be valid for the invocation scope
349+ of the closure we can use Higher-Ranked Trait Bounds with the ` for<...> ` syntax:
350+
351+ ``` ignore
352+ fn call_with_ref<F>(some_closure:F) -> i32
353+ where F: for<'a> Fn(&'a 32) -> i32 {
354+ ```
355+
356+ This lets the Rust compiler find the minimum lifetime to invoke our closure and
357+ satisfy the borrow checker's rules. Our function then compiles and excutes as we
358+ expect.
359+
360+ ```
361+ fn call_with_ref<F>(some_closure:F) -> i32
362+ where F: for<'a> Fn(&'a i32) -> i32 {
363+
364+ let mut value = 0;
365+ some_closure(&value)
366+ }
367+ ```
368+
322369# Function pointers and closures
323370
324371A function pointer is kind of like a closure that has no environment. As such,
@@ -344,7 +391,7 @@ assert_eq!(2, answer);
344391In this example, we don’t strictly need the intermediate variable ` f ` ,
345392the name of the function works just fine too:
346393
347- ``` ignore
394+ ``` rust, ignore
348395let answer = call_with_one(&add_one);
349396```
350397
0 commit comments