为什么即使实现IntoFuture也不能将Result视为Future?

时间:2018-10-29 22:53:53

标签: 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

1 个答案:

答案 0 :(得分:3)

Either仅在其两个子级都实现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特征与Future正交。如其文档所述:

  

此特征与IntoIterator特征非常相似,并且打算以非常相似的方式使用。

即使Iterator::map实现了Vec,也无法在vec![1, 2, 3].map(...)Vec)上调用IntoIterator,并且{{ 1}} / Result / Future


大多数时候,您将需要使用futures::ok

IntoFuture

您还可以选择直接致电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