gpt4 book ai didi

rust - 没有为实现 `poll` 的类型找到名为 `Future` 的方法

转载 作者:行者123 更新时间:2023-11-29 08:05:47 24 4
gpt4 key购买 nike

我正在尝试创建一个允许某人调用 .shutdown() 的结构,这将解决 future (否则未决)。它只能被调用一次。在 Future 特征的实现中,我收到一个错误,指出 poll 没有定义,尽管它存在于 the documentation 中。 (在 impl Future 下)。

尽管我使用 std::future::Future 作为 impl,但我尝试添加 use futures::prelude::* ,这会将预览特征纳入范围。 RLS 和 rustc 都通知我导入未使用,所以这不是问题。

请注意,我没有使用一个简单的 bool 标志,因为我打算让它能够从任何线程调用——这是一个与这里无关的实现细节。

use futures::channel::oneshot; // futures-preview@0.3.0-alpha.17
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};

pub struct ShutdownHandle {
sender: oneshot::Sender<()>,
receiver: oneshot::Receiver<()>,
}

impl ShutdownHandle {
pub fn new() -> Self {
let (sender, receiver) = oneshot::channel();
Self { sender, receiver }
}

pub fn shutdown(self) -> Result<(), ()> {
self.sender.send(())
}
}

impl Future for ShutdownHandle {
type Output = ();

fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
self.receiver.poll(&mut cx).map(|_| ())
}
}

fn main() {
let runner = ShutdownHandle::new();
assert!(runner.shutdown().is_ok());
}

我收到以下错误:

error[E0599]: no method named `poll` found for type `futures_channel::oneshot::Receiver<()>` in the current scope
--> src/main.rs:28:23
|
28 | self.receiver.poll(&mut cx).map(|_| ())
| ^^^^

我错过了什么?当然有一些方法可以“通过”投票。我每晚都在使用 (2019-07-18)。

最佳答案

这是真的,Receiver不执行 Future ;只有 Pin<&mut Receiver> 确实如此。您需要将类型的固定投影到字段。

当底层类型可能未实现时 Unpin

impl Future for ShutdownHandle {
type Output = ();

fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// I copied this code from Stack Overflow without reading the text that
// told me how to verify that this code uses `unsafe` correctly.
unsafe { self.map_unchecked_mut(|s| &mut s.receiver) }.poll(cx).map(|_| ())
}
}

您必须阅读 pin module彻底了解使用要求 unsafe在这里。

更清洁的解决方案

我喜欢使用辅助库,例如 pin_project ,处理更复杂的投影类型:

#[unsafe_project(Unpin)]
pub struct ShutdownHandle {
#[pin]
sender: oneshot::Sender<()>,
#[pin]
receiver: oneshot::Receiver<()>,
}

impl Future for ShutdownHandle {
type Output = ();

fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
let this = self.project();
this.receiver.poll(cx).map(|_| ())
}
}

当基础类型实现Unpin

Ömer Erden points out future 预览 crate 提供 FutureExt::poll_unpin .此方法采用对实现 Unpin 的类型的可变引用。并创建一个全新的 Pin用它。

oneshot::Receiver执行Unpin ,这可以在这里使用:

impl Future for ShutdownHandle {
type Output = ();

fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
self.receiver.poll_unpin(cx).map(|_| ())
}
}

另见

关于rust - 没有为实现 `poll` 的类型找到名为 `Future` 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57369123/

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