如何将 impl trait 传递给线程

How to pass impl trait to a thread

提问人:solomancode 提问时间:9/2/2023 更新时间:9/2/2023 访问量:32

问:

我试图将处理程序传递给每个传入请求的线程,我试图将其包装在 Arc 中,但出现以下错误:

参数类型的生存时间可能不够长impl ConnectionHandler

如何解决这个问题?

impl TCPConnectionHandler {
    pub async fn set_handler(&self, handler: impl ConnectionHandler) {
        let arc_handler = Arc::new(handler);
        loop {
            let handler_clone = arc_handler.clone();
            match self.0.accept().await {
                Ok((mut stream, addr)) => {
                    let join_handle = tokio::task::spawn(async move {    
                        handler_clone.on_incoming_connection(&addr);
                     // ^^^^^^^^^^^^^   
                     // ❌ the parameter type `impl ConnectionHandler` may not live long enough
                    });
                }
                Err(_) => {
                    panic!("Error accepting connection")
                }
            }
        }
    }
}
多线程 并发 Rust-Tokio 所有权

评论


答:

1赞 Peter Hall 9/2/2023 #1

仅仅因为将值包装在 an 中并不意味着它仍然不能包含非静态引用。Arc

例如,可以有一个类型 ,其中包含引用。类型 MyCoolConnectionHandler<'a> 仍包含引用。MyCoolConnectionHandler<'a>Arc<>

如果你的实现包含引用,你需要告诉该编译器,它可以通过将其限制在生存期内来做出该假设:ConnectionHandler'static

pub async fn set_handler(&self, handler: impl ConnectionHandler + 'static) {
   // ...
}

评论

0赞 solomancode 9/2/2023
删除 Arc 会导致以下错误,异步块可能比当前函数更长久,但它借用了当前函数所拥有的 。handler
0赞 solomancode 9/2/2023
虽然我有 Arc 没有问题,但如果我了解如何更新我的代码以允许删除 Arc,那就太好了。
0赞 Peter Hall 9/2/2023
如果你的连接类型是,那么你可以通过克隆它而不是包装它来避免。您需要将参数类型更改为:。CloneArcimpl ConnectionHandler + Clone + 'static