Add a note about Higher-Ranked Trait Bounds in docs on Closures.
When using closures that take references with explicit lifetimes sometimes it's required to use where F: for<..> ... syntax to express the right lifetimes. This adds a quick note to the docs so other users can discover it as well.
This commit is contained in:
parent
e88defe718
commit
7da9ea0af4
@ -319,6 +319,53 @@ assert_eq!(3, answer);
|
||||
Now we take a trait object, a `&Fn`. And we have to make a reference
|
||||
to our closure when we pass it to `call_with_one`, so we use `&||`.
|
||||
|
||||
A quick note about closures that use explicit lifetimes. Sometimes you might have a closure
|
||||
that takes a reference like so:
|
||||
|
||||
```
|
||||
fn call_with_ref<F>(some_closure:F) -> i32
|
||||
where F: Fn(&i32) -> i32 {
|
||||
|
||||
let mut value = 0;
|
||||
some_closure(&value)
|
||||
}
|
||||
```
|
||||
|
||||
Normally you can specify the lifetime of the parameter to our closure. We
|
||||
could annotate it on the function declaration:
|
||||
|
||||
```
|
||||
fn call_with_ref<'a, F>(some_closure:F) -> i32
|
||||
where F: Fn(&'a 32) -> i32 {
|
||||
```
|
||||
|
||||
However this presents a problem with in our case. When you specify the explict
|
||||
lifetime on a function it binds that lifetime to the *entire* scope of the function
|
||||
instead of just the invocation scope of our closure. This means that the borrow checker
|
||||
will see a mutable reference in the same lifetime as our immutable reference and fail
|
||||
to compile.
|
||||
|
||||
In order to say that we only need the lifetime to be valid for the invocation scope
|
||||
of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:
|
||||
|
||||
```
|
||||
fn call_with_ref<F>(some_closure:F) -> i32
|
||||
where F: for<'a> Fn(&'a 32) -> i32 {
|
||||
```
|
||||
|
||||
This lets the rust compiler find the minimum lifetime to invoke our closure and
|
||||
satisfy the borrow checker's rules. Our function then compiles and excutes as we
|
||||
expect.
|
||||
|
||||
```
|
||||
fn call_with_ref<F>(some_closure:F) -> i32
|
||||
where F: for<'a> Fn(&'a i32) -> i32 {
|
||||
|
||||
let mut value = 0;
|
||||
some_closure(&value)
|
||||
}
|
||||
```
|
||||
|
||||
# Function pointers and closures
|
||||
|
||||
A function pointer is kind of like a closure that has no environment. As such,
|
||||
|
Loading…
Reference in New Issue
Block a user