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
|
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 `&||`.
|
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
|
# Function pointers and closures
|
||||||
|
|
||||||
A function pointer is kind of like a closure that has no environment. As such,
|
A function pointer is kind of like a closure that has no environment. As such,
|
||||||
|
Loading…
Reference in New Issue
Block a user