rust - 为什么即使 Result 实现了 IntoFuture,也不能将其视为 Future?

标签 rust

std::result::Result工具 IntoFuture ,但以下代码无法编译:

extern crate futures; // 0.1.25

use futures::{future::Either, prelude::*, sync::mpsc};

fn example() -> impl Future<Item = (), Error = ()> {
    let (tx, rx) = mpsc::channel(0);
    let data = Some(1);
    match data {
        Some(d) => Either::A(tx.send(d).and_then(|x| Ok(())).map_err(|e| ())),
        None => Either::B(Ok(()) as Result<(), ()>),
    }
}

完整错误信息:

error[E0277]: the trait bound `std::result::Result<(), ()>: futures::Future` is not satisfied
 --> src/lib.rs:5:17
  |
5 | fn example() -> impl Future<Item = (), Error = ()> {
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `futures::Future` is not implemented for `std::result::Result<(), ()>`
  |
  = note: required because of the requirements on the impl of `futures::Future` for `futures::future::Either<futures::MapErr<futures::AndThen<futures::sink::Send<futures::sync::mpsc::Sender<{integer}>>, std::result::Result<(), futures::sync::mpsc::SendError<{integer}>>, [closure@src/lib.rs:9:50: 9:60]>, [closure@src/lib.rs:9:70: 9:76]>, std::result::Result<(), ()>>`
  = note: the return type of a function must have a statically known size

此外, IntoFuture 不需要 Sized .为什么不能Result<(), ()>被视为 Future在这里?

最佳答案

Either只有当它的两个 child 都实现了 Future 并且它们的类型一致时,才会实现 Future:

impl<A, B> Future for Either<A, B>
where
    A: Future,
    B: Future<Item = A::Item, Error = A::Error>, 

Result 实现Future ,因此将 Result 直接放在 Either 中也不会实现 Future

IntoFuture trait 与 Future 正交。正如其文档所述:

This trait is very similar to the IntoIterator trait and is intended to be used in a very similar fashion.

你不能在 Vec 上调用 Iterator::map (vec![1, 2, 3].map(...)),即使 Vec 实现了 IntoIterator,同样的逻辑也适用于 Result/Future/IntoFuture.


大多数时候,您会想要使用 futures::ok :

extern crate futures; // 0.1.25

use futures::{
    future::{self, Either},
    prelude::*,
    sync::mpsc,
};

fn example() -> impl Future<Item = (), Error = ()> {
    let (tx, _) = mpsc::channel(0);
    let data = Some(1);
    match data {
        Some(d) => Either::A(tx.send(d).map(|_| ()).map_err(|_| ())),
        None => Either::B(future::ok(())),
    }
}

您也可以选择直接调用into_future:

Either::B(Ok(()).into_future())

关于rust - 为什么即使 Result 实现了 IntoFuture,也不能将其视为 Future?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53055073/

相关文章:

rust - 如果 f32 不是 Eq,为什么会编译?

rust - 为什么 Rust 使用 "match"而不是 "switch"或 "case"?

ios - 在 Cargo Build 中为 iOS 目标启用位码输出?

pointers - 我如何在 Rust 中编写这个 C 函数?

rust - 为什么没有为明确实现的类型实现特征?

rust - serde如何将字符串中的值转换为类型

http - 如果(向客户端)传输的数据量超过了Content-Length,会发生什么情况?

rust - Actix-Web 2.0 JsonConfig error_handler无法正常工作

string - 如何检查字符串是否包含空格?

rust - 找不到目标 thumbv7em-none-eabihf 的 sin()、cos()、log10()( float )