简体   繁体   中英

Using higher order lifetime bounds for associated types

I would like to create a function - let's call it foo . I would like this function to take predicate parameter that is FnOnce Predicate takes one parameter t - reference of type T . Predicate returns Future that captures t lifetime.

Typical predicate can look like this: fn predicate<'a>(instance: &'a SomeType) -> Future<Output = ()> + 'a .

While I'm able to achieve this using higher order lifetime bounds and BoxFuture :

fn foo_boxed<T, E, R>(predicate: E)
where
    for<'a> E: FnOnce(&'a T) -> BoxFuture<'a, R> + Send + 'static,
    R: Send + 'static,
{
}

I would like to achieve the same result using generics only. It looks like for<'a> syntax matches the nearest parameter only, so the following won't compile:

fn foo_non_boxed_1<T, E, F>(predicate: E)
where
    for<'a> E: FnOnce(&'a T) -> F + Send + 'static,
    F: Future + Send + 'a, // 'a is undeclared here
    F::Output: Send + 'static,
{
}

Inside the foo I would like to store the predicate for later use and call it from another thread, passing T .

Is there any way to achieve this?

You need an extra trait to work around <Type as FnOnce(T) -> _>::Output not being valid, but here is a solution:

use std::future::Future;

trait MyFnOnce<T, O>: FnOnce(T) -> O {
    type Output;
}

impl<T, O, F> MyFnOnce<T, O> for F
where
    F: FnOnce(T) -> O,
{
    type Output = O;
}

fn foo_non_boxed_1<T, E, F>(predicate: E)
where
    E: for<'a> FnOnce(&'a T) -> F + Send + 'static,
    for<'a> <E as MyFnOnce<&'a T, F>>::Output: 'a,
    F: Future + Send,
    F::Output: Send + 'static,
{
}

Alternatively, on Nightly you don't need the extra trait but two feature flags:

#![feature(fn_traits, unboxed_closures)]

use std::future::Future;

fn foo_non_boxed_1<T, E, F>(predicate: E)
where
    E: for<'a> FnOnce(&'a T) -> F + Send + 'static,
    for<'a> <E as FnOnce<&'a T>>::Output: 'a,
    F: Future + Send,
    F::Output: Send + 'static,
{
}

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