简体   繁体   中英

How do I specify a closure that takes a reference and returns any type implementing a trait with the same lifetime as the reference?

I need to tell the compiler that F returns something that implements SomeTrait with the lifetime 'a :

trait SomeTrait {}

fn foo<P, Q, F>(func: F)
where
    Q: SomeTrait,
    F: for<'a> Fn(&'a P) -> Q + 'a,
{}

But I get this error:

error[E0261]: use of undeclared lifetime name `'a`
 --> src/main.rs:6:33
  |
6 |     F: for<'a> Fn(&'a P) -> Q + 'a,
  |                                 ^^ undeclared lifetime

It is like it doesn't understand Q + 'a .

Q is not a trait, it is a type; something like T: Q + 'a doesn't make sense.

If you try F: for<'a> Fn(&'a P) -> (Q + 'a) you'll get:

error[E0404]: expected trait, found type parameter `Q`

Your example actually parses like F: (for<'a> Fn(&'a P) -> Q) + 'a - and it should be obvious why that doesn't work.

Now to:

I need to tell the compiler that F returns something that implements SomeTrait with lifetime 'a .

Your function can't return different types depending on (passed) lifetimes apart from using those lifetimes for references or generic lifetime parameters. You could write a Rust compiler that simply ignores lifetimes completely, and if the original program was valid it would still do the same thing.

There is no way yet to specify type parameters that take generic parameters, for either lifetimes or types.

If there was, it could look like this:

trait SomeTrait {}

fn foo<P, for<'a> Q<'a>, F>(func: F)
where
    for<'a> Q<'a>: SomeTrait,
    for<'a> F: Fn(&'a P) -> Q<'a>,
{
}

Lifetimes can only be given to references . Changing the line to this works:

F: for<'a> Fn(&'a P) -> &'a Q

An object by itself does not have a "lifetime" as such - it lives until it is dropped. The borrow checker, however, must be informed of how long the object thst a reference points to lives relative to other referenced objects. That's where lifetimes come in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM