未找到实现`Future`的类型的名为`poll`的方法 [英] No method named `poll` found for a type that implements `Future`

查看:51
本文介绍了未找到实现`Future`的类型的名为`poll`的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个允许某人调用.shutdown()的结构,该结构将解决将来的问题(否则该问题将待处理).它只能被调用一次.在Future特征的实现中,尽管

I am attempting to create a struct that will allow someone to call .shutdown(), which will resolve a future (that is otherwise pending). It can only be called once. In the implementation of the Future trait, I receive an error that poll is not defined, despite it being present in the documentation (under impl Future).

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

Though I am using std::future::Future as the impl, I tried adding use futures::prelude::*, which would bring the preview trait into scope. Both RLS and rustc inform me that the import is unused, so that's not the issue.

请注意,我不是使用简单的布尔标志,因为我希望它可以从任何线程中调用,这是与此处无关的实现细节.

Note that I am not using a simple boolean flag, as I intend for this to be able to be callable from any thread — that's an implementation detail that is irrelevant here.

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).

What am I missing? Surely there's some way to "pass through" the polling. I am using nightly (2019-07-18).

推荐答案

是的,Receiver没有实现Future;只有 Pin<&mut Receiver> 可以.您需要投影从类型到字段的固定.

It's true, Receiver does not implement Future; only Pin<&mut Receiver> does. You need to project the pinning from your type to the field.

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模块以便全面了解在此处使用unsafe的要求.

You must read the pin module to thoroughly understand the requirements to use unsafe here.

我喜欢使用帮助程序库(例如 pin_project )来处理更复杂的投影类型:

I like to use a helper library, such as pin_project, to handle more complicated types of projection:

#[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

ÖmerErden指出,期货预览板条箱提供了 Unpin 并使用它创建一个全新的Pin.

When the underlying type implements Unpin

Ömer Erden points out that the futures-preview crate provides FutureExt::poll_unpin. This method takes a mutable reference to a type that implements Unpin and creates a brand new Pin with it.

由于oneshot::Receiver确实实现了Unpin,因此可以在此处使用它:

Since oneshot::Receiver does implement Unpin, this can be used here:

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(|_| ())
    }
}

另请参见

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆