返回未来类型时无法推断类型F

时间:2018-10-30 03:06:28

标签: rust rust-tokio

我正在尝试编写一个将返回Future的函数,因此在a tutorial from Tokio之后,我想到了:

extern crate tokio;

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

fn run<F>() -> impl Future<Item = (), Error = F::Error>
where
    F: Future<Item = ()>,
{
    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() {
    tokio::run(run());
}

playground

我收到此错误:

error[E0282]: type annotations needed
  --> src/main.rs:20:16
   |
20 |     tokio::run(run());
   |                ^^^ cannot infer type for `F`

我认为一旦指定了完整的返回类型,错误就会消失,我什至无法弄清楚(我的IDE给了我<futures::MapErr<futures::stream::ForEach<tokio::timer::Interval, [closure@src/ir.rs:24:23: 38:14 self:_], std::result::Result<(), tokio::timer::Error>>, [closure@src/ir.rs:39:22: 39:65]>

  1. 如何确定类型?有任何IDE提示或技巧吗? (我将Atom与ide-rust一起使用)
  2. 我能以某种方式摆脱仅定义impl Future<Item = (), Error = F::Error> where F: Future<Item = ()>吗?

    我可以在run函数内部的某个地方定义完整类型,但是我想在函数外部定义<Future<Item = (), Error = F::Error>><Future<Item = (), Error = io::Error>>

1 个答案:

答案 0 :(得分:2)

查看tokio::run的签名:

pub fn run<F>(future: F) 
where
    F: Future<Item = (), Error = ()> + Send + 'static, 

消耗的期货必须具有与Error相等的关联()类型。这意味着您不能对错误一视同仁。

这有效:

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() {
    tokio::run(run());
}