33个版本
0.5.20+已弃用 | 2022年12月19日 |
---|---|
0.5.19 | 2020年10月28日 |
0.5.18 | 2020年7月26日 |
0.5.15 | 2020年3月31日 |
0.1.0 | 2016年12月30日 |
#22 在 #hack
1,385,234 每月下载量
用于 少于 212 crates
42KB
820 行
表达式位置中的过程宏
注意: 截至Rust 1.45,此crate已被原生的 #[proc_macro] 在表达式位置的支持所取代。只有当您关心支持1.31到1.45之间的编译器时,才应考虑使用此crate。 |
自Rust 1.30以来,语言支持用户定义的类似函数的过程宏。然而,这些只能在项目位置调用,而不能在语句或表达式中调用。
此crate实现了一种可以在语句或表达式位置调用的过程宏的替代类型。
此方法与任何Rust 1.31+版本兼容。
定义过程宏
定义一个过程宏需要两个crate。
实现crate
此crate必须只包含过程宏。私有辅助函数和私有模块是可以的,但不能有任何公共内容。
就像您会使用 #[proc_macro] 属性来定义一个原生的支持过程宏一样,使用 proc-macro-hack 的 #[proc_macro_hack] 属性来定义一个在表达式位置工作的过程宏。函数签名与普通函数式过程宏相同。
use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;
use quote::quote;
use syn::{parse_macro_input, Expr};
#[proc_macro_hack]
pub fn add_one(input: TokenStream) -> TokenStream {
let expr = parse_macro_input!(input as Expr);
TokenStream::from(quote! {
1 + (#expr)
})
}
声明crate
如果您需要,此crate可以包含其他公共内容,例如特质、函数或普通宏。
在声明crate中需要从实现crate重新导出您的过程宏。重新导出也携带了 #[proc_macro_hack] 属性。
use proc_macro_hack::proc_macro_hack;
/// Add one to an expression.
///
/// (Documentation goes here on the re-export, not in the other crate.)
#[proc_macro_hack]
pub use demo_hack_impl::add_one;
两个crate都依赖于 proc-macro-hack
[dependencies]
proc-macro-hack = "0.5"
此外,您的实现crate(而不是您的声明crate)是一个过程宏crate
[lib]
proc-macro = true
使用过程宏
您的crate的用户依赖于您的声明crate(而不是您的实现crate),然后像往常一样使用您的过程宏。
use demo_hack::add_one;
fn main() {
let two = 2;
let nine = add_one!(two) + add_one!(2 + 3);
println!("nine = {}", nine);
}
限制
-
仅支持表达式位置的过程宏。模式位置的过程宏(#20)不受支持。
-
默认情况下,不支持嵌套调用,即由 proc-macro-hack 宏调用产生的代码不能包含对同一 proc-macro-hack 宏的递归调用,也不能调用其他任何 proc-macro-hack 宏。如果您需要支持嵌套调用,请使用
proc-macro-nested
。 -
默认情况下,卫生性结构使得展开的代码不能引用除宏输入中通过名称传递的局部变量以外的任何局部变量。如果您的宏必须引用在宏输入中没有命名的 局部 变量,请在您的声明包中对重导出使用
#[proc_macro_hack(fake_call_site)]
。 大多数宏不需要这个。 -
在足够新的编译器中,如果编译器原生支持表达式位置的 proc 宏,proc-macro-hack 不会自动使用该支持,因为两种实现之间的卫生性可能有所不同。要选择将您的宏编译为足够新编译器上的原生
#[proc_macro]
许可证
根据您的选择,许可协议为 Apache License, Version 2.0 或 MIT 许可证。除非您明确声明,否则根据 Apache-2.0 许可证定义,您提交的任何有意包含在此破解中的贡献将根据上述条款进行双重许可,没有任何额外的条款或条件。