Повторение задачи Rust с помощью tokio_timer

Я создаю повторяющуюся задачу в Rust с использованием фреймворка Tokio. Следующий код основан на заполненном запросе на изменение, чтобы добавить эту функцию в ящик с таймером Tokio.

При попытке компиляции я получаю сообщение об ошибке:

error[E0281]: type mismatch: the type `fn() {my_cron_func}` implements the trait `std::ops::FnMut<()>`, but the trait `std::ops::FnMut<((),)>` is required (expected tuple, found ())
  --> src/main.rs:19:36
   |
19 |     let background_tasks = wakeups.for_each(my_cron_func);
   |                                    ^^^^^^^^

error[E0281]: type mismatch: the type `fn() {my_cron_func}` implements the trait `std::ops::FnOnce<()>`, but the trait `std::ops::FnOnce<((),)>` is required (expected tuple, found ())
  --> src/main.rs:19:36
   |
19 |     let background_tasks = wakeups.for_each(my_cron_func);
   |                                    ^^^^^^^^

error[E0281]: type mismatch: the type `fn() {my_cron_func}` implements the trait `std::ops::FnMut<()>`, but the trait `std::ops::FnMut<((),)>` is required (expected tuple, found ())
  --> src/main.rs:20:10
   |
20 |     core.run(background_tasks).unwrap();
   |          ^^^
   |
   = note: required because of the requirements on the impl of `futures::Future` for `futures::stream::ForEach<tokio_timer::Interval, fn() {my_cron_func}, _>`

error[E0281]: type mismatch: the type `fn() {my_cron_func}` implements the trait `std::ops::FnOnce<()>`, but the trait `std::ops::FnOnce<((),)>` is required (expected tuple, found ())
  --> src/main.rs:20:10
   |
20 |     core.run(background_tasks).unwrap();
   |          ^^^
   |
   = note: required because of the requirements on the impl of `futures::Future` for `futures::stream::ForEach<tokio_timer::Interval, fn() {my_cron_func}, _>`

В сообщении об ошибке указывается, что возвращаемая подпись для функции my_cron_func неверна. Что мне нужно изменить / добавить, чтобы получить правильную подпись, чтобы она компилировалась?

extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;

use std::time::*;
use futures::*;
use tokio_core::reactor::Core;
use tokio_timer::*;

pub fn main() {

    println!("The start");
    let mut core = Core::new().unwrap();
    let timer = Timer::default();
    let duration = Duration::new(2, 0); // 2 seconds
    let wakeups = timer.interval(duration);

    // issues here
    let background_tasks = wakeups.for_each(my_cron_func);
    core.run(background_tasks).unwrap();

    println!("The end???");

}

fn my_cron_func() {
    println!("Repeating");
    Ok(());
}

1 ответ

Решение

Я не уверен, какая часть сообщения об ошибке вызывает у вас проблемы, но...

несоответствие типов

Вы указали неправильный тип

тип fn() {my_cron_func} реализует черту std::ops::FnMut<()>

Когда используешь my_cron_func, которая является функцией, которая не принимает аргументов

но черта std::ops::FnMut<((),)> необходимо

Но требуется функция, которая принимает один аргумент, пустой кортеж.

(ожидаемый кортеж, найден ())

И компилятор пытается сузить проблему.

Если вы просматриваете документацию для библиотеки, которую вы используете, в частности, tokio_timer::Interval Вы можете видеть, что он реализует futures::Stream со связанным типом Item = (),

Это меняет сообщение об ошибке:

error[E0277]: the trait bound `(): futures::Future` is not satisfied
  --> src/main.rs:19:36
   |
19 |     let background_tasks = wakeups.for_each(my_cron_func);
   |                                    ^^^^^^^^ the trait `futures::Future` is not implemented for `()`
   |
   = note: required because of the requirements on the impl of `futures::IntoFuture` for `()`

error[E0277]: the trait bound `(): futures::Future` is not satisfied
  --> src/main.rs:20:10
   |
20 |     core.run(background_tasks).unwrap();
   |          ^^^ the trait `futures::Future` is not implemented for `()`
   |
   = note: required because of the requirements on the impl of `futures::IntoFuture` for `()`
   = note: required because of the requirements on the impl of `futures::Future` for `futures::stream::ForEach<tokio_timer::Interval, fn(()) {my_cron_func}, ()>`

Просмотр документации для futures::Stream мы можем видеть, что замыкание перешло к for_each необходимо вернуть значение, которое можно превратить в будущее, которое приведет к ():

fn for_each<F, U>(self, f: F) -> ForEach<Self, F, U> 
    where F: FnMut(Self::Item) -> U,
          U: IntoFuture<Item=(), Error=Self::Error>,
          Self: Sized

Ваша функция пытается что-то вернуть, за исключением того, что нет возвращаемого типа, и вы использовали ; завершить функцию:

fn my_cron_func(a: ()) {
    println!("Repeating");
    Ok(());
}

futures::future::ok делает трюк:

fn my_cron_func(_: ()) -> futures::future::FutureResult<(), tokio_timer::TimerError> {
    println!("Repeating");
    futures::future::ok(())
}
Другие вопросы по тегам