Rollup merge of #33611 - vvanders:master, r=steveklabnik
Add a note about Higher-Ranked Trait Bounds in docs on Closures. I hit a snag with lifetimes a few days ago and it wasn't until @birkenfeld pointed out Higher-Ranked Trait Bounds that I was able to solve the issue involving lifetimes on closure traits. This adds a small section in the book so that other users can find it. r? @steveklabnik
This commit is contained in:
commit
e4f33d5ae7
@ -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:
|
||||
|
||||
```ignore
|
||||
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:
|
||||
|
||||
```ignore
|
||||
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…
x
Reference in New Issue
Block a user