具有正确函数签名的不兼容类型

Leo*_*nti 5 rust

我有 2 个返回相同类型的函数 impl Future<Item = (), Error = ()>

extern crate tokio;
extern crate futures;

use tokio::timer::Interval;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use futures::future;

fn run2() -> impl Future<Item = (), Error = ()> {
    future::ok(())
}

fn run() -> impl Future<Item = (), Error = ()> {
    Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}", instant);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e))
}

fn main_run() -> impl Future<Item = (), Error = ()> {
    if 1 == 1 {
        run()
    } else {
        run2()
    }
}

fn main() {
    tokio::run(main_run());
}
Run Code Online (Sandbox Code Playgroud)

操场

我试图在 中有条件地执行函数main_run,但我收到一个奇怪的错误:

error[E0308]: if and else have incompatible types
  --> src/main.rs:23:5
   |
23 | /     if 1 == 1 {
24 | |         run()
25 | |     } else {
26 | |         run2()
27 | |     }
   | |_____^ expected opaque type, found a different opaque type
   |
   = note: expected type `impl futures::Future` (opaque type)
          found type `impl futures::Future` (opaque type)
Run Code Online (Sandbox Code Playgroud)

两个函数都返回相同的类型:impl Future<Item = (), Error = ()>
为什么编译器不高兴?

编辑:
由于它是重复的,我在对原始问题的回答中找到了一个解决方案,但是如果将来有人偶然发现这个问题,这里是这个特定问题的解决方案:

extern crate tokio;
extern crate futures;

use tokio::timer::Interval;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use futures::future;

fn run2() -> Box<Future<Item = (), Error = ()> + Send> {
    Box::new(future::ok(()))
}

fn run() -> Box<Future<Item = (), Error = ()> + Send> {
    Box::new(Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}", instant);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e)))
}

fn main_run() -> impl Future<Item = (), Error = ()> {
    if 1 == 1 {
        run()
    } else {
        run2()
    }
}

fn main() {
    tokio::run(main_run());
}
Run Code Online (Sandbox Code Playgroud)

游乐场