gpt4 book ai didi

asynchronous - 对 tokio::spawn(async move) 中的变量生命周期感到困惑

转载 作者:行者123 更新时间:2023-12-03 11:26:01 29 4
gpt4 key购买 nike

我是 rust 和 tokio async 的新手,我正在尝试编译以下看似简单的代码:

async fn network_handler(network_config: &config::NetworkConfig) -> Result<(), Error> {
Ok(())
}

pub async fn run(network_config: &config::NetworkConfig) -> Result<(), Error> {
let network_config_copy = network_config.clone();
tokio::spawn(async move {
network_handler(&network_config_copy).await
}).await?
}

但是编译器提示:
error: cannot infer an appropriate lifetime
--> src/network.rs:43:18
|
43 | pub async fn run(network_config: &config::NetworkConfig) -> Result<(), Error> {
| ^^^^^^^^^^^^^^ ...but this borrow...
44 | let network_config_copy = network_config.clone();
45 | tokio::spawn(async move {
| ------------ this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'_` as defined on the function body at 43:34
--> src/network.rs:43:34
|
43 | pub async fn run(network_config: &config::NetworkConfig) -> Result<(), Error> {
| ^
help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the function body at 43:34
|
45 | tokio::spawn + '_(async move {
| ^^^^^^^^^^^^^^^^^

从我在该主题上找到的先前讨论和示例中,我了解到将对 network_config 的引用传递给 spawn-ed 闭包会导致生命周期问题,因为单独的线程可能会超过 network_config。
这就是为什么我将 network_config 的克隆移动到生成的线程,但似乎仍然存在终生歧义。

是否有任何额外的提示我可以给编译器以便它正确地获得生命周期?还是我做错了整件事?

注意:NetworkConfig 类定义为:
#[derive(Debug, Deserialize)]
pub struct NetworkConfig {
pub bind: String,
pub node_key_file: String,
}

最佳答案

如果你想克隆 NetworkConfig为它声明 Clone 的值特征:

#[derive(Debug, Clone)]
pub struct NetworkConfig {
pub bind: String,
pub node_key_file: String,
}

否则,对于接收器方法查找的规则,您最终将调用 Clone通过引用
以下 Clone implementer :
impl<'_, T> Clone for &'_ T

并且克隆的引用将具有绑定(bind)到 clone() 范围的生命周期。调用。

derive(Clone) run函数编译,但它仅在 network_config 时有效参数有 'static生命周期,因为 tokio::spawn生命周期要求。

可能这不是你想要的。如果是这种情况,请通过 NetworkConfig按值并最终在调用者中克隆它
语境。
use async_std::io::Error;
use tokio;

mod config {

#[derive(Debug, Clone)]
pub struct NetworkConfig {
pub bind: String,
pub node_key_file: String,
}
}

async fn network_handler(network_config: &config::NetworkConfig) -> Result<(), Error> {
println!("using {:?}", network_config);
Ok(())
}

pub async fn run(network_config: config::NetworkConfig) -> Result<(), Error> {
tokio::spawn(async move { network_handler(&network_config).await }).await?
}

#[tokio::main]
async fn main() {
let config = config::NetworkConfig {
bind: "my_bind".to_owned(),
node_key_file: "abc".to_owned(),
};

tokio::spawn(run(config.clone()));
}

您可能会问为什么这样有效,实际上仍然将引用传递给 network_handler() .

这是因为 network_config在 spawn async block 内移动并且
这使得异步 block 的推断类型获得静态生命周期。

关于asynchronous - 对 tokio::spawn(async move) 中的变量生命周期感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60688816/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com