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

qwe*_*iop 2 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<(), ()>),
    }
}
Run Code Online (Sandbox Code Playgroud)

完整的错误信息:

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<(), ()>),
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,IntoFuture不需要Sized. 为什么不能Result<(), ()>当作Future这里来对待?

She*_*ter 5

EitherFuture当它的两个子级实现Future和它们的类型对齐时才实现:

impl<A, B> Future for Either<A, B>
where
    A: Future,
    B: Future<Item = A::Item, Error = A::Error>, 
Run Code Online (Sandbox Code Playgroud)

Result没有实现Future,这样,将一个Result直接内部的Either将不执行Future任何。

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

此特征与 trait 非常相似,IntoIterator旨在以非常相似的方式使用。

你可以不叫Iterator::map上一个Vecvec![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(())),
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Either::B(Ok(()).into_future())
Run Code Online (Sandbox Code Playgroud)