understanding error: trait `futures::future::Future` is not implemented for `()`
understanding error: trait `futures::future::Future` is not implemented for `()`
这个问题是关于如何阅读 Rust 文档并提高我对 Rust 的理解,从而了解如何解决这个特定的编译器错误。
我已阅读 tokio docs and experimented with many of the examples。在编写自己的代码时,我经常 运行 遇到我不理解的编译器错误,并且经常发现我可以修复代码,但不理解 为什么 具体语法是需要。
我根据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(())
});
}
以上代码不正确,需要注释掉Ok()
。我知道这是真的,但不完全是为什么。这可能是先前问题 的另一半——现在我更了解闭包,但不能完全解析文档以理解预期的 return 值。
当我尝试编译上面不正确的代码时,出现以下错误:
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 `()`
我的问题分为两部分:
- 错误消息试图告诉我什么?
- 我如何使用 and_then 的文档来理解预期的 return 值?
基本上您传递给 and_then
的闭包类型错误。它预计:
F: FnOnce(Self::Item) -> B
但是你给它一个单位类型的闭包,即returns没有值。因此错误。
也就是说,rustc
错误消息在这里不是最佳选择。如果是这样就更好了:
let client = TcpStream::connect(&addr).and_then(|stream| {
println!("created stream");
// error: mismatched types: expected `IntoFuture` but found `()`
});
rust-lang 项目有这个 ticket 来跟踪上述诊断问题的进展。
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,
这意味着:
- 您的闭包必须接受
Self::Item
类型的参数和 return 某种类型 B
- 由闭包编辑的
B
return 类型必须可转换为 future。
- 如果未来 return 是一个错误,那么该错误的类型必须是
Self::Error
。
此外,如果您查看 IntoFuture
, you will see that it is implemented for Result
的文档,那么它适用于 Ok(())
,但未针对 ()
实现,因此如果你的闭包 return 没什么。
这个问题是关于如何阅读 Rust 文档并提高我对 Rust 的理解,从而了解如何解决这个特定的编译器错误。
我已阅读 tokio docs and experimented with many of the examples。在编写自己的代码时,我经常 运行 遇到我不理解的编译器错误,并且经常发现我可以修复代码,但不理解 为什么 具体语法是需要。
我根据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(())
});
}
以上代码不正确,需要注释掉Ok()
。我知道这是真的,但不完全是为什么。这可能是先前问题
当我尝试编译上面不正确的代码时,出现以下错误:
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 `()`
我的问题分为两部分:
- 错误消息试图告诉我什么?
- 我如何使用 and_then 的文档来理解预期的 return 值?
基本上您传递给 and_then
的闭包类型错误。它预计:
F: FnOnce(Self::Item) -> B
但是你给它一个单位类型的闭包,即returns没有值。因此错误。
也就是说,rustc
错误消息在这里不是最佳选择。如果是这样就更好了:
let client = TcpStream::connect(&addr).and_then(|stream| {
println!("created stream");
// error: mismatched types: expected `IntoFuture` but found `()`
});
rust-lang 项目有这个 ticket 来跟踪上述诊断问题的进展。
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,
这意味着:
- 您的闭包必须接受
Self::Item
类型的参数和 return 某种类型B
- 由闭包编辑的
B
return 类型必须可转换为 future。 - 如果未来 return 是一个错误,那么该错误的类型必须是
Self::Error
。
此外,如果您查看 IntoFuture
, you will see that it is implemented for Result
的文档,那么它适用于 Ok(())
,但未针对 ()
实现,因此如果你的闭包 return 没什么。