繁体   English   中英

包装 AsyncRead `self` 具有匿名生命周期 `'_`,但它需要满足 `'static` 生命周期要求

[英]Wrapping AsyncRead `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement

我正在尝试将AsyncRead包装在另一个AsyncRead中(并对其进行一些数据处理)。 但是,当尝试存储.read()Future时,我遇到了生命周期问题: self has an anonymous lifetime '_ but it needs to satisfy a 'static lifetime requirement

代码:

pub struct AsyncReadWrap {
    input: Pin<Box<dyn AsyncRead + 'static>>,
    future: Option<Pin<Box<dyn Future<Output = std::io::Result<usize>>>>>
}

impl AsyncReadWrap {
    pub fn new(input: impl AsyncRead + Unpin + 'static) -> AsyncReadWrap {
        AsyncReadWrap {
            input: Box::pin(input),
            future: None
        }
    }
}

impl AsyncRead for AsyncReadWrap {
    fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<std::io::Result<()>> {
        
        let mut buffer = [0u8; 2048];
        let future = self.input.as_mut().read(&mut buffer);
        self.future = Some(Box::pin(future));
       
        Poll::Pending
    }
}

我是异步的新手,奇怪的是在poll函数中没有一些简单的方法来await 谢谢你。

您不能从poll function 中调用await ,因为await可能会调用多次poll并将让控制权返回给其间的执行程序。 单个poll调用可能只产生一次,并且只能通过另一个poll调用来恢复。 轮询和期货是async / await的构建块 - 在使用较低级别的实现时,您不能使用更高级别的抽象。

您当前代码的问题在于您的 struct 是self-referential input.read()返回可能从input借用的未来:

// `Read` borrows from `self` and `buf`
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> 

您不能将返回的未来存储在您的结构中,因为在同一个结构中存储一个值和对该值的引用是有问题的

要创建AsyncRead包装器,您可以在内部AsyncRead poll_read poll_read返回Ready时,缓冲区将被读取的值填充,您可以对其进行数据处理:

impl AsyncRead for AsyncReadWrap {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, mut buf: &mut ReadBuf<'_>) -> Poll<std::io::Result<()>> {
        match self.input.as_mut().poll_read(cx, &mut buf) {
            Poll::Ready(res) => {
                // do stuff with `buf`
                Poll::Ready(res)
            },
            Poll::Pending => Poll::Pending
        }
    }
}

poll_read function 中执行更多async操作将变得复杂,因为您必须跟踪AsyncRead实现将处于的多个状态。 async / await是对未来 state 机器的抽象。 如果您不一定需要实现AsyncRead ,则可以完全避免较低级别的期货,只需将其设为async方法:

pub async fn read(mut input: impl AsyncRead + Unpin) -> Vec<u8> {
    let mut buf = [0u8; 1024];
    input.read(&mut buf).await;
    // ...
    buf.to_vec()
}

如果您选择 go 低级路线,这里有一些有用的资源:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM