6 个版本
0.1.5 | 2023 年 5 月 21 日 |
---|---|
0.1.4 | 2023 年 5 月 21 日 |
1562 在 Rust 模式
每月 66 次下载
23KB
452 行
orderless!
orderless
为您生成宏,允许您在 Rust 中使用无序/命名函数。
#[make_orderless(defs(a = 2))]
fn add(a: usize, b: usize) -> usize {
a + b
}
// Compiles to add(2, 2) for no runtime performance hit!
add!(b = 2); // 4
功能
- 属性宏。
- 过程宏。
- 函数路径(来自包和
impl
的函数)。 - 默认参数值。
- 标识符。
- 表达式。
-
const
和static
变量。 - 可选地不提供默认值。
- 快捷方式将相同名称和值简化为仅名称。
a = a
到a
。 - 属性宏
impl_orderless
为make_orderless
在impl
块中。
文档
文档提供在 docs.rs。
它如何工作?
调用 call_orderless!
call_orderless!
是执行所有重工作的过程宏。它接受一些信息,如函数的名称、参数的顺序和默认值。
call_orderless! {
func = two,
order(a, b),
defs(a = false, b = false),
args(a = true, b = false),
}
正如您所看到的,单独使用它并没有什么意义。但它非常适合其他宏将其信息传递给它。
创建 call_orderless!
create_orderless!
是另一个辅助宏。它通过生成一个具有大部分内置信息的 macro_rules!
宏来简化编写 call_orderless!
的过程。
create_orderless! {
func = two,
order(a, b),
defs(a = false, b = false)
}
// Generates...
// Note `order(...)` disappears because it's integrated into `defs(...)` by `create_orderless!`.
macro_rules! two {
( $($arg_name:ident $(= $arg_value:expr)?),*$(,)? ) => {
::orderless::call_orderless!(
func = two,
defs(a = false, b = false),
args($($arg_name $(= $arg_value)?),*),
)
};
() => {
::orderless::call_orderless!(
func = two,
defs(a = false, b = false),
args(),
)
};
}
// Called like...
two!(b = true);
现在您有一个类似于函数的宏,可以非常简单地进行使用。
make_orderless
make_orderless
是一个属性宏,它通过获取函数定义中已存在的信息来进一步简化过程。
#[make_orderless(defs(a = false, b = false))]
fn two<T>(a: T, b: T) -> (T, T) {
(a, b)
}
// Generates the same thing as `create_orderless!`...
impl_orderless
make_orderless
的主要问题在于它直接生成一个macro_rules!
宏,因此不能在impl
块中使用。
struct Args {}
impl Args {
#[make_orderless(defs(a = false, b = false))] // ERROR!!
pub fn two(a: bool, b: bool) -> (bool, bool) {
(a, b)
}
}
幸运的是,impl_orderless
宏使这成为可能。
struct Args {}
#[impl_orderless]
impl Args {
#[make_orderless(defs(a = false, b = false))] // SUCCESS!!
pub fn two(a: bool, b: bool) -> (bool, bool) {
(a, b)
}
}
它是通过删除所有make_orderless
属性并将它们转换为create_orderless!
来实现的,这些转换在impl
块之外。
所有这些链式调用都形成了宏的嵌套。一个将宏转换为另一个宏的宏,该宏创建一个宏,该宏调用另一个宏。但最终,这些都属于编译时,对运行时性能没有影响。two!()
简单地编译为two(false, false)
!
依赖项
~1.6–2.2MB
~42K SLoC