I think what I'm asking is best explained with code. I want to do the following...
struct Foo {
foo: Box<dyn for<'a> Fn(&'a Bar) -> Baz + 'a>,
}
ie. I want to store a function, with the lifetime of the output tied to the lifetime of the parameter. Is this possible?
The + 'a
in dyn Fn(...) -> ... + 'a
denotes the lifetime of the function (trait object), not the lifetime of the output. You need to read this as dyn Trait + 'a
with Trait
being Fn(...) -> ...
, the +
binds weaker than the ->
.
In your code example, the output type Baz
has no lifetimes attached at all. If the output type was, say, &Baz
, then relating it to the function input type as in dyn for<'a> Fn(&'a Bar) -> &'a Baz
would work perfectly well; in fact dyn Fn(&Bar) -> &Baz
would even be a shorthand for this (using lifetime elision).
2 Likes
One other point of possible clarification:
If Baz
is actually a struct Baz<'a> { /* ... */ }
, elision works the same as with &Baz
, and thus these are all the same:
dyn for<'a> Fn(&'a Bar) -> Baz
dyn for<'a> Fn(&'a Bar) -> Baz<'a>
dyn Fn(&Bar) -> Baz
dyn Fn(&Bar) -> Baz<'_>
The elision on Baz
is confusing as it can lead you to think the function return doesn't borrow from the inputs , so Baz<'a>
or Baz<'_>
are recommended.
1 Like