@@ -319,6 +319,53 @@ assert_eq!(3, answer);
319
319
Now we take a trait object, a ` &Fn ` . And we have to make a reference
320
320
to our closure when we pass it to ` call_with_one ` , so we use ` &|| ` .
321
321
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
+
322
369
# Function pointers and closures
323
370
324
371
A function pointer is kind of like a closure that has no environment. As such,
@@ -344,7 +391,7 @@ assert_eq!(2, answer);
344
391
In this example, we don’t strictly need the intermediate variable ` f ` ,
345
392
the name of the function works just fine too:
346
393
347
- ``` ignore
394
+ ``` rust, ignore
348
395
let answer = call_with_one(&add_one);
349
396
```
350
397
0 commit comments