Option<Box<dyn Future>当在异步函数递归生成的流中实现时。如何投票Pin<Option<Box<dyn Future>>?谢谢。
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use futures_util::Stream;
#[pin_project::pin_project]
struct BoxedStream<T, F> {
#[pin]
next: Option<String>,
#[pin]
inner: Option<Box<dyn Future<Output = T>>>,
// ^--- Future generated by async function, it is an opaque type.
generate: F,
}
impl<T, F> Stream for BoxedStream<T, F>
where
F: Fn(String) -> (Option<String>, Box<dyn Future<Output = T>>),
{
type Item = T;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut p = self.as_mut().project();
if let Some(s) = p.inner.as_mut().as_pin_mut() {
return match todo!("how to do it here? s.poll(cx)?") {
result @ Poll::Ready(_) => {
p.inner.take();
result
}
_ => Poll::Pending,
};
}
if let Some(next) = p.next.take() {
let (next, future) = (p.generate)(next);
p.inner.set(Some(future));
p.next.set(next);
return self.poll_next(cx);
}
Poll::Ready(None) // end
}
}
Run Code Online (Sandbox Code Playgroud)
s.poll(cx)当我代替待办事项时报告的错误:
error[E0599]: the method `poll` exists for struct `Pin<&mut Box<dyn Future<Output = T>>>`, but its trait bounds were not satisfied
--> src/lib.rs:28:28
|
28 | return match s.poll(cx)? {
| ^^^^ method cannot be called on `Pin<&mut Box<dyn Future<Output = T>>>` due to unsatisfied trait bounds
--> /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/future/future.rs:37:1
|
= note: doesn't satisfy `_: Unpin`
--> /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/alloc/src/boxed.rs:195:1
::: /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/alloc/src/boxed.rs:198:1
|
= note: doesn't satisfy `_: Future`
|
= note: the following trait bounds were not satisfied:
`(dyn futures_util::Future<Output = T> + 'static): Unpin`
which is required by `Box<(dyn futures_util::Future<Output = T> + 'static)>: futures_util::Future`
Run Code Online (Sandbox Code Playgroud)
Pin<Option<...>>没有任何意义;Pin仅当它包装的类型是一种指针时才有效。
您应该存储inner为 aOption<Pin<Box<dyn Future>>>并跳过 的结构固定#[pin]。没有理由Option<Box<...>>需要固定其本身(这意味着#[pin]通过制作 a ,只需要固定inner: Pin<&mut Option<Box<...>>>内部,这就是 a 的含义。dyn FuturePin<Box<...>>
同样,你也不需要或不想next被结构性地固定。因此,只需删除所有#[pin]注释并从那里开始:
#[pin_project::pin_project]
struct BoxedStream<T, F> {
next: Option<String>,
inner: Option<Pin<Box<dyn Future<Output = T>>>>,
generate: F,
}
impl<T, F> Stream for BoxedStream<T, F>
where
F: Fn(String) -> (Option<String>, Pin<Box<dyn Future<Output = T>>>),
{
type Item = T;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let p = self.as_mut().project();
if let Some(s) = p.inner {
return match s.as_mut().poll(cx) {
Poll::Ready(result) => {
p.inner.take();
Poll::Ready(Some(result))
}
_ => Poll::Pending,
};
}
if let Some(next) = p.next.take() {
let (next, future) = (p.generate)(next);
*p.inner = Some(future);
*p.next = next;
return self.poll_next(cx);
}
Poll::Ready(None)
}
}
Run Code Online (Sandbox Code Playgroud)
我还让你的函数类型返回Pin<Box<...>>,它可以很容易地通过Box::pin.