Rust 如何创建过程宏属性?

Rust 如何创建过程宏属性?,rust,rust-macros,rust-proc-macros,Rust,Rust Macros,Rust Proc Macros,既然有了proc\u宏,我们如何创建这样的东西呢 从我所看到的,可以在fn whatsitsiname(attrs:TokenStream,code:TokenStream)->TokenStream上添加#[proc\u macro\u属性]注释,但如何注册它呢?如何添加自定义属性?如果我理解正确,您可以: 创建一个proc_macro类型的板条箱,即其货物。toml应包含 [lib] proc-macro = true 在该板条箱中,创建带有#[proc\u macro\u属性]注释的

既然有了
proc\u宏
,我们如何创建这样的东西呢

从我所看到的,可以在
fn whatsitsiname(attrs:TokenStream,code:TokenStream)->TokenStream
上添加
#[proc\u macro\u属性]
注释,但如何注册它呢?如何添加自定义属性?

如果我理解正确,您可以:

  • 创建一个
    proc_macro
    类型的板条箱,即其
    货物。toml
    应包含

    [lib]
    proc-macro = true
    
  • 在该板条箱中,创建带有
    #[proc\u macro\u属性]
    注释的实现。函数类宏的
    #[proc_macro]
    和自定义派生的
    #[proc_macro_deriver]
    的工作原理相同,只是它们只有一个
    令牌流
    参数。这些在
    proc\u宏
    板条箱中定义

    第一个标记流是属性中的参数,第二个是带注释项的主体

  • 然后在想要使用宏的板条箱中,只需依赖proc_宏板条箱和 使用
    #[macro\u use]
    属性导入它(
    #[macro\u use]外部板条箱
    …)

这应该足够了


应该扩展,以提及
#[proc_macro_derivate]
之外的其他proc宏类型。这可能是一个bug。

Rust编译器有一个相当完整的代码。在寻找新引入功能的示例时,我经常从以下方面入手:

$rg-c proc_宏_属性
src/test/run pass fulldeps/auxiliary/proc_macro_def.rs:2
src/test/ui fulldeps/auxiliary/attr\u proc\u macro.rs:1
[…35场其他比赛…]
下面是一个充分发挥作用的示例:

$tree
.
├── 货舱
├── my_宏
│   ├── 货舱
│   ├── src
│   │   └── 图书馆
└── src
└── 梅因
Cargo.toml

我们在定义宏的板条箱上添加了一个依赖项

[软件包]
name=“foo”
version=“0.1.0”
authors=[“一个devlooper和是这两项任务的当前黄金标准。处理
TokenStream
包括在以及中

还有
#[proc_macro]
,其函数形式如下:

#[proc_macro]
pub fn the_name_of_the_macro(input: TokenStream) -> TokenStream

这本书包含了一个@SvenMarnach,它只解释了
proc\u macro\u派生
,而不是
proc\u macro\u属性
@llogiq我知道这一点,但是这个链接可能对其他登陆这里的人有用。(你的第一个问题是“我想说的是,它们应该被记录在@SvenMarnach链接的书附录中,如果它们没有被记录,那么这是一个bug,应该在跟踪问题中报告和引用(它仍然是开放的,没有提到记录特性,但可能应该)。
extern crate proc_macro;

use proc_macro::*;

#[proc_macro_attribute]
pub fn log_entry_and_exit(args: TokenStream, input: TokenStream) -> TokenStream {
    let x = format!(r#"
        fn dummy() {{
            println!("entering");
            println!("args tokens: {{}}", {args});
            println!("input tokens: {{}}", {input});
            println!("exiting");
        }}
    "#,
            args = args.into_iter().count(),
            input = input.into_iter().count(),
    );

    x.parse().expect("Generated invalid tokens")
}
#[proc_macro]
pub fn the_name_of_the_macro(input: TokenStream) -> TokenStream