英文:
Type erasure of a closure that returns an async block
问题
Certainly, here's the translated code without the comments:
|entity: &mut Entity| async move {
entity.foo().await;
}
fn main() {
erase_and_store(|entity: &mut Entity| async move {
entity.foo().await;
});
}
fn erase_and_store<'a, C, F>(closure: C) -> Task where
C: FnOnce(&'a mut Entity) -> F,
F: Future<Output = ()> + 'a {
Task::Variant(/* TODO convert closure to something that can be stored */)
}
enum Task {
Variant(/* TODO store closure */)
}
Please note that the comments indicating "TODO" are not translated as they are code placeholders specific to the programming task.
英文:
Consider the following closure that returns an async block:
|entity: &mut Entity| async move {
entity.foo().await;
}
Is it possible to type erase and store this closure inside an enum, without specifying a generic type or lifetime on that enum? Consider the following MWE:
use std::future::Future;
struct Entity;
impl Entity {
async fn foo(&mut self) {}
}
fn main() {
erase_and_store(|entity: &mut Entity| async move {
entity.foo().await;
});
}
fn erase_and_store<'a, C, F>(closure: C) -> Task where
C: FnOnce(&'a mut Entity) -> F,
F: Future<Output = ()> + 'a {
Task::Variant(/* TODO convert closure to something that can be stored */)
}
enum Task {
Variant(/* TODO store closure */)
}
I have tried a couple different approaches but it seems that even if I put everything behind boxed trait objects, I can not stop this generic lifetime 'a
from leaking through to my Task
enum.
type AnyFuture<'a> = Box<dyn Future<Output = ()> + 'a>;
type AnyClosure<'a> = Box<dyn FnOnce(&'a mut Entity) -> AnyFuture<'a>>;
enum Task {
Variant(AnyClosure) // requires <'a>
}
答案1
得分: 3
你想要的是一个更高排名的生命周期:
type AnyFuture<'a> = Pin<Box<dyn Future<Output = ()> + 'a>>;
type AnyClosure = Box<dyn for<'a> FnOnce(&'a mut Entity) -> AnyFuture<'a>>;
可以省略为:
type AnyFuture<'a> = Pin<Box<dyn Future<Output = ()> + 'a>>;
type AnyClosure = Box<dyn FnOnce(&mut Entity) -> AnyFuture<'_>>;
英文:
What you want is a higher-ranked lifetime:
type AnyFuture<'a> = Pin<Box<dyn Future<Output = ()> + 'a>>;
type AnyClosure = Box<dyn for<'a> FnOnce(&'a mut Entity) -> AnyFuture<'a>>;
That can be elided:
type AnyFuture<'a> = Pin<Box<dyn Future<Output = ()> + 'a>>;
type AnyClosure = Box<dyn FnOnce(&mut Entity) -> AnyFuture<'_>>;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论