0
extern crate tokio; // 0.1.8

use tokio::prelude::*;

fn create_a_future(x: u8) -> Box<Future<Item = (), Error = ()>> {
    Box::new(futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    }))
}

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }
}

これが標準出力に出力されることを期待していますが、そうはなりませんでした。私spawnは間違った方法で使用していますか?

4

1 に答える 1

1

コメントで既に述べたように、一連の計算を設定していますが、実行することはありません。イテレータと同様に、future はlazyと考えることができます。フューチャを直接作成するが使用しない場合、コンパイラは通常これについて通知します。ここでは先物を生成しているので、その警告は表示されませんが、Tokio 原子炉を駆動するものは何もありません。

多くの場合、実行したい特定の未来があり、それが完了するまで原子炉を運転します。それ以外の場合は、reactor を「永久に」実行し、新しい作業を際限なく処理します。

この場合、次を使用できますCore::turn

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }

    eloop.run(None);
}

eloop.turn(None);

-> Box<Future<Item = (), Error = ()>>

現代の Rust では、これを行う必要はありません (おそらく行うべきではありません)。匿名型を返すことをお勧めします:

fn create_a_future() -> impl Future<Item = (), Error = ()> {
    futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    })
}
 tokio_core::reactor::Core

私の理解では、このレベルの Tokio は、より複雑なセットアップ用に予約されています。多くの人は単にtokio::runand を使うことができますtokio::spawn:

fn main() {
    tokio::run(futures::lazy(|| {
        for _ in 0..10 {
            tokio::spawn(create_a_future());
        }
        Ok(())
    }))
}
于 2018-10-26T23:16:44.420 に答える