Confused about variable lifetime in tokio::spawn(async move

后端 未结 1 2087
囚心锁ツ
囚心锁ツ 2020-12-18 10:51

I am new to rust and tokio async, and I am trying to compile the following seemingly straightforward code:

async fn network_handler(network_config: &conf         


        
相关标签:
1条回答
  • 2020-12-18 11:53

    If you want clone the NetworkConfig value declare for it the Clone trait:

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

    Otherwise, for the rules of receiver method lookup you will end up with invoking a Clone on a reference through the following Clone implementer:

    impl<'_, T> Clone for &'_ T
    

    And the cloned reference will have a lifetime bound to scope of clone() invocation.

    With derive(Clone) the run function compiles, but it works only when network_config argument has 'static lifetime, because of tokio::spawn lifetime requirement.

    Probably this is not what you want. If this is the case pass NetworkConfig by value and eventually clone it in the caller context.

    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()));
    }
    

    You may ask why this works, indeed a reference is still passed to network_handler().

    This is because network_config is moved inside the spawn async block and this makes gaining static lifetime for the inferred type of the async block.

    0 讨论(0)
提交回复
热议问题