理解错误:特性 `futures::future::Future` 没有为 `()` 实现

Ult*_*rus 5 rust rust-tokio

这个问题是关于如何阅读 Rust 文档并提高我对 Rust 的理解,从而了解如何解决这个特定的编译器错误。

我已经阅读了tokio 文档并尝试了许多示例。在编写自己的代码时,我经常遇到我不理解的编译器错误,并且经常发现我可以修复代码,但不明白为什么需要特定的语法。

我复制了一个基于 tokio 的hello world的非常简单的例子:

use futures::Future;
use tokio::net::TcpStream;
use tokio::prelude::*;

fn main() {
  let addr = "127.0.0.1:6142".parse().unwrap();

  let client = TcpStream::connect(&addr).and_then(|stream| {
      println!("created stream");
      // Process stream here.

      // Ok(())
  });

}
Run Code Online (Sandbox Code Playgroud)

上面的代码不正确,需要注释掉Ok()。我知道这是真的,但不知道为什么。这可能是之前问题的另一半如何解释 read_until 的签名以及 Tokio 中的 AsyncRead + BufRead 是什么?- 现在我更好地理解闭包,但不能完全解析文档以理解预期的返回值。

当我尝试编译上面不正确的代码时,出现以下错误:

error[E0277]: the trait bound `(): futures::future::Future` is not satisfied
 --> tokio-chat-client/src/main.rs:8:42
  |
8 |   let client = TcpStream::connect(&addr).and_then(|stream| {
  |                                          ^^^^^^^^ the trait `futures::future::Future` is not implemented for `()`
  |
  = note: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`
Run Code Online (Sandbox Code Playgroud)

我的问题有两个部分:

  1. 试图告诉我的错误消息是什么?
  2. 我将如何使用and_then的文档来了解预期的返回值?

Jmb*_*Jmb 5

文档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, 
Run Code Online (Sandbox Code Playgroud)

这意味着:

  • 你的闭包必须接受一个类型的参数Self::Item并返回一些类型B
  • B闭包返回的类型必须可以转换为未来。
  • 如果该未来返回错误,则该错误必须具有 type Self::Error

此外,如果您查看 for 的文档IntoFuture,您会看到它是为实现的Result,因此它适用于Ok(()),但它没有实现为(),因此如果您的闭包不返回任何内容,则它不起作用。