简体   繁体   English

使用TcpConnectionNew时,不满足特征绑定`():futures :: Future`

[英]The trait bound `(): futures::Future` is not satisfied when using TcpConnectionNew

I am trying to write a simple TCP client in Rust using Tokio crate. 我正在尝试使用Tokio板条箱在Rust中编写一个简单的TCP客户端。 My code is pretty close to this example minus the TLS: 我的代码非常接近此示例,减去了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. 我觉得很奇怪,因为根据文档应该将其实现。

I'm using 我正在使用

  • Rust 1.19.0 锈病1.19.0
  • futures 0.1.16 期货0.1.16
  • tokio-core 0.1.10 东京核心0.1.10
  • tokio-io 0.1.3 东京io 0.1.3

What am I missing? 我想念什么?

TL;DR: remove the semicolon after io::write_all . TL; DR:删除io::write_all之后的分号。


Review the definition of and_then : 查看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, 

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 ). 闭包( F )必须返回某种类型( B ),该类型( B )可以转换为将来的类型( B: IntoFuture ),其错误类型与起始闭包( Error = Self::Error )相匹配。

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 () ": ()没有实现特征IntoFuture ,该特征由错误消息部分“在futures::IntoFuture for ()futures::IntoFuture

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

Removing the semicolon will cause the Future returned by io::write_all to be returned back to and_then and the program will compile. 删除分号将使io::write_all返回的Future返回到and_then ,程序将编译。

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. 请牢记这一点,因为使用此类组合器时几乎总是需要返回未来。

Unfortunately the answer here is quite specific, but the question turns up for any kind of search for: 不幸的是,这里的答案是非常具体的,但是对于任何形式的搜索,问题都会出现:

the trait futures::Future is not implemented for () 特质futures::Future未针对()实现

A typical scenario for this kind of error is: 这种错误的典型情况是:

foo.then(|stream| {
    // ... Do random things here
    final_statement();
});

This causes an error because the majority of the extension functions require the return type to implement IntoFuture . 这会导致错误,因为大多数扩展功能都需要返回类型来实现IntoFuture However, () does not implement IntoFuture , and by terminating the block with a ; 但是, ()无法实现IntoFuture ,并且IntoFuture使用;终止该块; the implicit return type is () . 隐式返回类型为()

However, IntoFuture is implemented for Option and Result . 但是, IntoFuture OptionResult

Rather than just randomly removing semicolons vaguely in the hope this will somehow magically make your code compile, consider: 考虑到希望以某种方式神奇地使代码编译,而不仅仅是模糊地随机删除分号,请考虑:

You should be returning something that can be converted into a Future using IntoFuture . 您应该返回可以使用IntoFuture转换为Future IntoFuture

If you don't have a specific promise that you're returning, consider returning Ok(()) to say simply 'this is done' from your callback: 如果您没有明确的承诺要返回,请考虑返回Ok(())以便从回调中简单地说“已完成”:

foo.then(|stream| {
    // ... Do random things here
    final_statement();
    return Ok(()); // <-- Result(()) implements `IntoFuture`.
});

Note specifically I terminate this block with an explicit return statement; 注意,具体来说,我使用显式的return语句终止此块。 this is deliberate. 这是故意的。 This is a typical example of how the ergonomics of 'can omit semicolon to implicitly return object' is tangibly harmful; 这是“省略分号以隐式返回对象”的人机工程学对人类有害的典型示例。 terminating the block with Ok(()); Ok(());终止块Ok(()); will continue to fail with the same error. 将继续失败,并出现相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用bash找出tcp端口是否绑定(不监听) - Find out whether tcp port is bound (not listening) using bash 当服务使用 LOCALHOST 并使用 2 个 IP 地址时,它们如何绑定到端口? - How are services bound to port effected when they use LOCALHOST and 2 IP addresses are used? 当绑定到 VPN / utun 接口也使用的特定以太网接口时,套接字如何连接? - How can a socket connect when bound to a specific ethernet interface that's also being used by VPN / utun interface? 对 TcpStreams 的 Read trait 如何工作的误解 - Misunderstanding of how the Read trait works for TcpStreams 当绑定到“ 0.0.0.0”时,如何找到我的Java ServerSocket绑定到的实际接口IP地址? - When binding to “0.0.0.0”, how to find the actual interface IP address that my Java ServerSocket was bound to? ServerSocket复用地址是否允许绑定到已经绑定的端口? - ServerSocket reuseAddress allow bind to an already bound port? 使用socket编程时fork - Fork when using socket programming Akka Tcp绑定消息用法 - Akka Tcp bound message usage 如何在Tokio未来链的多个分支中使用TcpStream? - How to use a TcpStream in multiple branches of a Tokio future chain? 确定客户端绑定的TCP端口号 - Determining the TCP port number to which client got bound
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM