这个问题是关于如何阅读Rust文档并增进我对Rust的理解,从而了解如何解决这个特定的编译器错误。
我已经阅读了tokio docs,并尝试了许多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()
。我知道这是事实,但不完全是原因。这也许是先前问题How do I interpret the signature of read_until and what is AsyncRead + BufRead in Tokio?的另一半-现在,我对闭包有了更好的了解,但无法完全解析文档以了解期望的返回值。
当我尝试编译上面的错误代码时,出现以下错误:
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 `()`
我的问题有两个部分:
答案 0 :(得分:1)
基本上,您传递给and_then
的闭包类型错误。期望:
F: FnOnce(Self::Item) -> B
但是您给它一个单位类型的闭包,即不返回任何值。因此,错误。
也就是说,rustc
错误消息在这里不是最佳的。如果它显示为:
let client = TcpStream::connect(&addr).and_then(|stream| {
println!("created stream");
// error: mismatched types: expected `IntoFuture` but found `()`
});
rust-lang项目使用此ticket来跟踪有关诊断问题的进度。
答案 1 :(得分:1)
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
类型的参数,并返回某种B
类型的B
必须转换为将来的类型。Self::Error
。此外,如果您查看IntoFuture
的文档,您会发现它是implemented for Result
,因此它适用于Ok(())
,但并未为{{1 }},因此如果您的闭包不返回任何内容,它将不起作用。