22

我正在尝试在 Rust 中编写自己的派生模式宏,并且它的文档在示例中有些缺乏。

我有一个像这样的结构:

#[derive(MyMacroHere)]
struct Example {
    id: i64,
    value: Option<String>,
}

我希望我的宏生成一个方法 à la

fn set_fields(&mut self, id: i64, value: Option<String>) {
    // ...
}

使用TokenStreamtrait 实现类似目标的基本步骤是什么?

4

1 回答 1

27
  1. 为您的程序宏创建一个 crate:

     cargo new my_derive --lib
    
  2. 编辑 Cargo.toml 使其成为程序宏箱:

     [lib]
     proc-macro = true
    
  3. 实现你的程序宏:

     extern crate proc_macro;
    
     use proc_macro::TokenStream;
    
     #[proc_macro_derive(MyMacroHere)]
     pub fn my_macro_here_derive(input: TokenStream) -> TokenStream { 
         // ...
     }
    
  4. 导入程序宏并使用它:

     extern crate my_derive;
    
     use my_derive::MyMacroHere;
    
     #[derive(MyMacroHere)]
     struct Example {
         id: i64,
         value: Option<String>,
     }
    

困难的部分是宏的实现。大多数人使用synquote crate 来解析传入的 Rust 代码,然后生成新代码。

例如,syn 的文档以自定义派生的示例开头。您将解析结构(或枚举或联合),然后处理定义结构(单元、元组、命名字段)的各种方式。您将收集您需要的信息(类型,也许是名称),然后您将生成适当的代码。

也可以看看:

于 2018-11-03T23:31:52.723 回答