在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
内)的第二次调用将闭包转换为未来?
答案 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
的这两个方面实际上是相同的。
另请参阅: