[英]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 我正在使用
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
是为Option
和Result
。
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.