1 个不稳定版本
0.1.0 | 2024 年 4 月 4 日 |
---|
#640 在 Rust 模式
32KB
224 行(不包括注释)
延迟宏和 Rust 工具
延迟执行 Rust 工具。
此 crate 提供了用于在 Rust 中延迟执行代码的实用结构体和宏。它允许您指定在作用域退出时(如函数结束或代码块执行完成后)应执行的操作。
特性
-
延迟语句:该库引入了
Defer
延迟语句的概念,提供与其他编程语言中找到的功能相似的功能。该Defer
结构允许您注册在活动作用域退出时执行的功能或闭包。 -
DeferGroup:该
DeferGroup
结构允许您将多个延迟操作组合在一起。当DeferGroup
退出作用域时,所有注册的操作将以相反的顺序执行。 -
宏支持:宏
defer!
和defer_scope!
简化了创建延迟操作的过程。它们可以用来延迟函数调用、闭包或任意代码块。
安装
要使用 defer
库,将其添加到您的 Cargo.toml
中的依赖项。
[dependencies]
defer-rs = "0.1"
使用方法
1. 使用 defer!
宏
defer!
宏简化了创建延迟操作的过程。它支持函数调用和任意代码块。
示例
use defer_rs::defer;
defer!({
println!("Deferred action using macro");
});
// ... other code ...
// The deferred action will be executed when it goes out of scope
2. 使用 defer_scope!
宏
defer_scope!
宏可以与 defer_scope_init!
宏结合使用,以精确管理在延迟语句执行结束时的作用域。
示例
use defer_rs::{defer_scope, defer_scope_init};
use std::cell::Cell;
let val = Cell::new(0);
{
defer_scope_init!(); // Initiate scoped deferred collection
{
defer_scope!(val.set(1)); // Add to it in a nested scope
assert_eq!(val.get(), 0);
}
// `defer_scope!(val.set(1))` is still to run, even though the scope containing it has ended!
assert_eq!(val.get(), 0);
// ... other code ...
// The deferred collection will execute the contained closures when it goes out of scope on the following line
}
assert_eq!(val.get(), 1)
3. 使用 Defer
结构体
Defer
结构体用于创建单个延迟操作。您可以通过提供不带参数的闭包或函数来创建一个新的延迟操作。当 Defer
实例退出作用域时,提供的闭包或函数将被执行。
注意:defer!
宏是这个结构体的语法糖。
示例
use defer_rs::Defer;
let deferred_action = Defer::new(|| {
println!("Deferred action executed!");
});
// ... other code ...
// deferred_action will be executed when it goes out of scope
4. 组合延迟操作
DeferGroup
结构体允许您将多个延迟操作组合在一起。当 DeferGroup
退出作用域时,操作将以相反的顺序执行。
注意:宏 defer_scope!
和 defer_scope_init!
是该结构和它的 ::add()
方法的语法糖。
示例
use defer_rs::DeferGroup;
let mut defer_group = DeferGroup::new();
defer_group.add(Box::new(|| {
println!("First deferred action");
}));
defer_group.push(Box::new(|| {
println!("Second deferred action");
}));
// ... other code ...
// Both deferred actions will be executed in reverse order
5. 宏特殊案例:通过值捕获闭包的环境
在 'defer!' 或 'defer_scope!' 宏中的语句前加上 move
关键字将捕获闭包的环境值。
注意:这与向 Defer::new()
或 DeferGroup::add()
传递的闭包中添加 move
相同。
示例
use defer_rs::{defer_scope, defer_scope_init};
let val = "Variable that must be passed by value!";
defer_scope_init!(); // Initiate scoped deferred collection
{
defer_scope!(move {
println!("`val` is captured by value!");
println!("{}", val);
});
}
6. 宏特殊案例:立即评估传递的参数
有时希望将传递给延迟函数调用的参数在延迟时评估,而不是在延迟执行的延迟时间(类似于 Go
和其他编程语言中 defer
关键字的工作方式),当在单独的函数调用上使用 'defer!'(或 'defer_scope!') 宏时,将模拟此行为。
注意:可以通过在传递给宏的函数调用后加上 ;
来禁用此行为。
示例
use defer_rs::{defer_scope, defer_scope_init};
use std::cell::{Cell, RefCell};
use std::io::Write;
fn add_to_buffer(to_add: String, buff: &RefCell<Vec<u8>>) {
writeln!(buff.borrow_mut(), "{to_add}");
}
let buff = RefCell::new(Vec::new());
let buff2 = RefCell::new(Vec::new());
let val = Cell::new(0);
defer_scope_init!();
defer_scope ! {
let res = b"x is: 3\n";
assert_eq!(*buff.borrow(), res.to_vec());
let res = b"x is: 0\n";
assert_eq!(*buff2.borrow(), res.to_vec());
};
// This will evaluate the arguments passed to the invoked at function at call time (deferred-to time / later), `val.get()` results in `3`
defer_scope!(
add_to_buffer(
format!("x is: {}", val.get()),
&buff
); // Notice the `;` at the end of the function call, disables the immediate evaluation of passed arguments.
);
// This will evaluate the arguments passed to the invoked function at time of macro invocation (now), `val.get()` results in `0`
defer_scope!(
add_to_buffer(
format!("x is: {}", val.get()),
&buff2
) // No `;`. Arguments are immediately evaluated!
);
val.set(3);
长例
use defer_rs::{defer, defer_scope, defer_scope_init};
use std::cell::Cell;
fn print(to_print: String) {
println!("{to_print}");
}
fn main() {
let x = Cell::new(0);
defer_scope_init!();
{
// The macro deferrs execution of the code passed to it to the end of the scope of the nearest `DeferGroup` (or `defer_scope_init!` invocation) going up
defer_scope!({
println!("This will be printed 13th/last");
});
defer_scope!(
println!("This will be printed 12th");
);
{
let x = Cell::new(1);
// Define a new DeferGroup
defer_scope_init!();
// This will evaluate the arguments passed to the invoked at function at time of macro invocation (now), results in `0`
// Using `defer!` here instead of `defer_scope!` will result in identical behavior!
defer_scope!(print(format!("This will be printed 1st, x is: {}", x.get())));
x.set(3);
}
// `defer!` will delay the execution of code passed to it until the end of it's containg scope!
defer! { move
println!("This will be printed 3rd");
println!("This will be printed 4th");
};
defer_scope! {
println!("This will be printed 11th");
};
defer! { move
println!("This will be printed 2nd");
};
}
println!("This will be printed 5th");
// This will evaluate the arguments passed to the invoked at function at time of macro invocation (now), `x.get()` results in `0`
defer_scope!(print(format!("This will be printed 10th, x is: {}", x.get())));
// This will evaluate the arguments passed to the invoked at function at call time (deferred-to time, later), `x.get()` results in `3`
defer!({ print(format!("This will be printed 8th, x is: {}", x.get())) });
x.set(3);
defer_scope! {
println!("This will be printed 9th");
};
println!("This will be printed 6th");
defer! {
println!("This will be printed 7th");
};
}
这将导致以下行被打印到 stdout
This will be printed 1st, x is: 1
This will be printed 2nd
This will be printed 3rd
This will be printed 4th
This will be printed 5th
This will be printed 6th
This will be printed 7th
This will be printed 8th, x is: 3
This will be printed 9th
This will be printed 10th, x is: 0
This will be printed 11th
This will be printed 12th
This will be printed 13th/last
许可证
根据您的选择,在 Apache License, Version 2.0 或 MIT 许可证 下许可。除非您明确说明,否则您故意提交给包括在此软件包中并由 Apache-2.0 许可证定义的贡献,将根据上述条件双重许可,而无需附加条款或条件。
依赖关系
~255–700KB
~17K SLoC