futures::future::lazy 有什么用?
What is futures::future::lazy for?
在 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(())
}));
对此的解释是:
The lazy
function runs the closure the first time the future is polled. It is used here to ensure that tokio::spawn
is called from a task. Without lazy
, tokio::spawn
would be called from outside the context of a task, which results in an error.
尽管对 Tokio 有一些了解,但我不确定我是否准确理解了这一点。看来这两个lazy
的作用略有不同,这个解释只适用于第一个。第二次调用 lazy
(在 for
循环内)不就是为了将闭包转换为 future 吗?
lazy 的目的 包含在 documentation for lazy
:
Creates a new future which will eventually be the same as the one created by the closure provided.
The provided closure is only run once the future has a callback scheduled on it, otherwise the callback never runs. Once run, however, this future is the same as the one the closure creates.
就像普通闭包一样,它用于防止代码被急切求值。用同步术语来说,就是调用函数和调用函数返回的闭包的区别:
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
的这两个方面实际上是一样的。
另请参阅:
在 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(())
}));
对此的解释是:
The
lazy
function runs the closure the first time the future is polled. It is used here to ensure thattokio::spawn
is called from a task. Withoutlazy
,tokio::spawn
would be called from outside the context of a task, which results in an error.
尽管对 Tokio 有一些了解,但我不确定我是否准确理解了这一点。看来这两个lazy
的作用略有不同,这个解释只适用于第一个。第二次调用 lazy
(在 for
循环内)不就是为了将闭包转换为 future 吗?
lazy 的目的 包含在 documentation for lazy
:
Creates a new future which will eventually be the same as the one created by the closure provided.
The provided closure is only run once the future has a callback scheduled on it, otherwise the callback never runs. Once run, however, this future is the same as the one the closure creates.
就像普通闭包一样,它用于防止代码被急切求值。用同步术语来说,就是调用函数和调用函数返回的闭包的区别:
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
的这两个方面实际上是一样的。
另请参阅: