英文:
How to move generic typed parameter to an async move block?
问题
我正在尝试用Rust编写一些东西(我很喜欢但经验不多),发现了一个我不知道如何解决的障碍。
我的意图是生成一个异步任务,将初始状态作为参数传递。异步任务将接受该值(可以保持所有权)并进一步使用它。问题是初始值需要是一个泛型。但我收到了一个关于StateT
生命周期的错误,并且我无法让编译器知道我想要将其移动/复制到异步块中。
async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
StateT: Send,
{
tokio::spawn(async move {
process(initial_value);
})
}
我尝试过将StateT: Copy + Send + Sync
等等,但编译器不喜欢。只有'static
能够编译通过,但我想这不是正确的(它不是我将传递的常量,而是某个任意的结构体)。
错误消息是:
error[E0310]: the parameter type `StateT` may not live long enough
--> src/workflow2.rs:7:5
|
7 | / tokio::spawn(async move {
8 | | process(initial_value);
9 | | })
| |______^ ...so that the type `StateT` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
5 | StateT: Send + 'static,
| +++++++++
如果我尝试传递i32
或String
而不是泛型,它可以正常工作。所以我想我可能是缺少一些适用于StateT
的特质约束,以提供所缺少的内容。
英文:
I'm trying to write something in Rust (which I love but don't have much experience yet) and found a hurdle I have no idea how to sort out.
My intention is to spawn an asynchronous task passing an initial state as parameter. The asynchronous task will take that value (it can keep ownership of it) and use it further. Thing is the initial value needs to be a generic. And I get an error complaining about the lifetime of StateT
and I cannot let the compiler know that I want to move it / copy it to the async block.
async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
StateT: Send,
{
tokio::spawn(async move {
process(initial_value);
})
}
I tried making StateT: Copy + Send + Sync
, etc but it doesn't like it. Only 'static
works but I guess that's not right (it's not a constant that I will pass, but some arbitrary struct).
The error message is:
error[E0310]: the parameter type `StateT` may not live long enough
--> src/workflow2.rs:7:5
|
7 | / tokio::spawn(async move {
8 | | process(initial_value);
9 | | })
| |______^ ...so that the type `StateT` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
5 | StateT: Send + 'static,
| +++++++++
If I try passing an i32
or a String
instead of the generic it works just fine. So I guess I'm missing some trait bound for StateT
that provides what's missing.
答案1
得分: 5
只有 'static 起作用,但我猜这不对(它不是我要传递的常量,而是某个任意的结构体)。
这是Rust 常见生命周期误解#2:T: 'static
不意味着 T
存活于整个程序,并且更不意味着 T
是一个常量。它仅表示 T
是一个完全独立的类型,不借用任何其他数据。因此,在这里使用 StateT: 'static
是正确的做法:
async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
StateT: Send + 'static,
{
tokio::spawn(async move {
process(initial_value);
})
}
英文:
> Only 'static works but I guess that's not right (it's not a constant that I will pass, but some arbitrary struct).
This is common Rust lifetime misconception #2: T: 'static
does not mean that T
lives for the entire program, and even less that T
is a constant. It only means that T
is a fully self-contained type and that it doesn't borrow any other data. So StateT: 'static
is the right thing to do here:
async fn start<StateT>(initial_value: StateT) -> impl futures::Future
where
StateT: Send + 'static,
{
tokio::spawn(async move {
process(initial_value);
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论