Не могу вывести тип F при возврате типа Future - PullRequest
0 голосов
/ 30 октября 2018

Я пытаюсь написать функцию, которая бы возвращала Future, поэтому, следуя учебнику из 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());
}

площадка

Я получаю эту ошибку:

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 голосов
/ 30 октября 2018

Посмотрите на подпись 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());
}
...