gpt4 book ai didi

asynchronous - 包装 AsyncRead `self` 具有匿名生命周期 `' _` but it needs to satisfy a ` 'static` 生命周期要求

转载 作者:行者123 更新时间:2023-12-04 14:59:34 24 4
gpt4 key购买 nike

我正在尝试包装 AsyncRead在另一个 AsyncRead (并对其进行一些数据处理)。但是,当尝试存储 Future 时的 .read()我遇到终身问题: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
}
}

我是异步的新手,奇怪的是没有一些简单的方法来 awaitpoll职能。谢谢你。

最佳答案

您不能调用 await来自 poll函数,因为 await可调用poll多次,并在两者之间将控制权交还给执行者。单poll调用只能产生一次,并且只能通过另一个 poll 恢复调用。投票和 future 是 async 的基石/await - 在使用较低级别的实现时,您不能使用较高级别的抽象。
您当前代码的问题在于您的结构是自引用的。 input.read()返回可以从 input 借用的 future :

// `Read` borrows from `self` and `buf`
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
您不能将返回的 future 存储在您的结构中,因为 storing a value and a reference to that value in the same struct is problematic .
创建 AsyncRead包装器,您可以调用 poll_read在内部 AsyncRead .当 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
}
}
}
表演更多 async poll_read里面的操作函数将变得复杂,因为您必须跟踪 AsyncRead 的多个状态实现将在。 async/ await是对较低级别的 future 状态机的抽象。如果您不一定需要实现 AsyncRead ,您可以完全避免使用较低级别的 future ,只需将其设为 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()
}
如果您选择走低级路线,这里有一些有用的资源:
  • Async in depth
  • Pin and suffering
  • Async/Await
  • 关于asynchronous - 包装 AsyncRead `self` 具有匿名生命周期 `' _` but it needs to satisfy a ` 'static` 生命周期要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67244233/

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