使用 TcpConnectionNew 时不满足 trait bound `(): futures::Future` [英] The trait bound `(): futures::Future` is not satisfied when using TcpConnectionNew

查看:18
本文介绍了使用 TcpConnectionNew 时不满足 trait bound `(): futures::Future`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Tokio crate 在 Rust 中编写一个简单的 TCP 客户端.我的代码非常接近 这个例子 减去 TLS:

I am trying to write a simple TCP client in Rust using Tokio crate. My code is pretty close to this example minus the TLS:

extern crate futures;
extern crate tokio_core;
extern crate tokio_io;

use futures::Future;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use tokio_io::io;

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let connection = TcpStream::connect(&"127.0.0.1:8080".parse().unwrap(), &handle);

    let server = connection.and_then(|stream| {
        io::write_all(stream, b"hello");
    });

    core.run(server).unwrap();
}

但是,编译失败并显示错误:

However, compilation fails with the error:

error[E0277]: the trait bound `(): futures::Future` is not satisfied
  --> src/main.rs:16:29
   |
16 |     let server = connection.and_then(|stream| {
   |                             ^^^^^^^^ the trait `futures::Future` is not implemented for `()`
   |
   = note: required because of the requirements on the impl of `futures::IntoFuture` for `()`

error[E0277]: the trait bound `(): futures::Future` is not satisfied
  --> src/main.rs:20:10
   |
20 |     core.run(server).unwrap();
   |          ^^^ the trait `futures::Future` is not implemented for `()`
   |
   = note: required because of the requirements on the impl of `futures::IntoFuture` for `()`

我觉得很奇怪,因为根据文档 应该实施.

I find it strange because according to the documentation it should be implemented.

我正在使用

  • Rust 1.19.0
  • 期货 0.1.16
  • tokio 核心 0.1.10
  • tokio-io 0.1.3

我错过了什么?

推荐答案

TL;DR:去掉io::write_all后的分号.

TL;DR: remove the semicolon after io::write_all.

查看and_then的定义:

fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F> 
where
    F: FnOnce(Self::Item) -> B,
    B: IntoFuture<Error = Self::Error>,
    Self: Sized, 

闭包 (F) 必须返回某种类型 (B),该类型可以转换为未来 (B: IntoFuture)与起始闭包匹配的错误类型 (Error = Self::Error).

The closure (F) has to return some type (B) that can be converted into a future (B: IntoFuture) with an error type that matches the starting closure (Error = Self::Error).

你的闭包会返回什么?<代码>().这是为什么?因为您在行的末尾放置了一个分号 (;).()实现trait IntoFuture,由错误信息部分在futures::IntoFuture for ()的impl上"表示:

What does your closure return? (). Why is that? Because you've placed a semicolon (;) at the end of your line. () does not implement the trait IntoFuture, which is indicated by the error message part "on the impl of futures::IntoFuture for ()":

impl<F: Future> IntoFuture for F {
    type Future = F;
    type Item = F::Item;
    type Error = F::Error;
}

去掉分号会导致io::write_all返回的Future返回给and_then,程序将编译.

Removing the semicolon will cause the Future returned by io::write_all to be returned back to and_then and the program will compile.

一般来说,futures 的工作原理是将较小的组件组​​合在一起,这些组件本身就是 futures.所有这些共同构建一个单一的大未来,它本质上是一个状态机.记住这一点很好,因为在使用此类组合器时,您几乎总是需要返回一个未来.

In general, futures work by combining together smaller components which are themselves futures. All of this works together to build a single large future which is essentially a state machine. It's good to keep this in mind, as you will almost always need to return a future when using such combinators.

这篇关于使用 TcpConnectionNew 时不满足 trait bound `(): futures::Future`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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