期货::期货::懒惰的目的是什么?

时间:2019-06-11 13:06:57

标签: rust future rust-tokio

Tokio documentation中,我们有以下代码段:

extern crate tokio;
extern crate futures;

use futures::future::lazy;

tokio::run(lazy(|| {
    for i in 0..4 {
        tokio::spawn(lazy(move || {
            println!("Hello from task {}", i);
            Ok(())
        }));
    }

    Ok(())
}));

对此的解释是:

  

lazy函数在第一次对未来进行轮询时运行闭包。在此用于确保从任务中调用tokio::spawn。如果没有lazy,将tokio::spawn从任务上下文之外调用,这将导致错误。

尽管对Tokio有所了解,但我不确定我是否能准确理解。看来这两个lazy的角色略有不同,并且此说明仅适用于 first 一个。不是只是在这里lazy循环内(在for内)的第二次调用将闭包转换为未来?

1 个答案:

答案 0 :(得分:4)

documentation for lazy涵盖了懒惰的目的

  

创建一个新的未来,最终将与所提供的闭包创建的未来相同。

     

所提供的闭包仅在将来安排了回调时才运行,否则该回调将永远不会运行。但是,一旦运行,这个未来与关闭所创建的未来相同。

就像普通的闭包一样,它用于防止对代码进行急切的评估。用同步术语来说,调用函数和调用函数返回的闭包之间是有区别的:

fn sync() -> impl FnOnce() {
    println!("This is run when the function is called");

    || println!("This is run when the return value is called")
}

fn main() {
    let a = sync();
    println!("Called the function");
    a();
}

与期货0.1的平行线:

use futures::{future, Future}; // 0.1.27

fn not_sync() -> impl Future<Item = (), Error = ()> {
    println!("This is run when the function is called");

    future::lazy(|| {
        println!("This is run when the return value is called");
        Ok(())
    })
}

fn main() {
    let a = not_sync();
    println!("Called the function");
    a.wait().unwrap();
}

使用async / await语法,该功能不再需要:

#![feature(async_await)] // 1.37.0-nightly (2019-06-05)

use futures::executor; // 0.3.0-alpha.16
use std::future::Future;

fn not_sync() -> impl Future<Output = ()> {
    println!("This is run when the function is called");

    async {
        println!("This is run when the return value is called");
    }
}

fn main() {
    let a = not_sync();
    println!("Called the function");
    executor::block_on(a);
}

您已经确定,Tokio的示例使用lazy进行以下操作:

  • 确保闭包中的代码仅从执行程序内部运行。
  • 确保关闭可以作为将来运行

我认为lazy的这两个方面实际上是相同的。

另请参阅: