Rust 过程宏 proc-macro2 和 proc-macro 主要区别

软件开发大郭
0 评论
/
20 阅读
/
2024 字
03 2023-12

The proc-macro2 crate is a drop-in replacement for  proc_macro  except that it is available outside of macros - which makes it testable. Its types are all convertible to and from the  proc_macro  types and have identical methods.

The usual pattern for writing a nontrivial macro is to use  proc_macro  only for the entry point, and use  proc-macro2  for all of the real work:

extern crate proc_macro;use proc_macro2::TokenStream; #[proc_macro]pub fn my_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {    let output = transform_stream(TokenStream::from(input));    proc_macro::TokenStream::from(output)} // A testable function!fn transform_stream(input: TokenStream) -> TokenStream {    // actual work goes here}

It's common to import items from  proc-macro2  so they can be used unqualified, and just used fully qualified names for  proc_macro , since the only time you will use it is in the entry point. It's also usual to put the core components in a separate library crate, which does not have a dependency on  proc_macro .

In tests, you can create a  TokenStream  from a string:

use std::str::FromStr;let ts = TokenStream::from_str("fn foo() {}").unwrap();

在  Rust  中,编写过程宏,必须在  Cargo.toml  中设置  [lib]proc-macro = true ,这样就导致该库只能用于编写过程宏代码,无法在其他库中编写  proc-macro  代码,比如在其他包中无法使用  use proc_macro::TokenStream; ,这样就很难对宏代码进行单元测试。

所以第三方提供了  proc-macro2  这样的包,可以在任何库类型中编写过程宏代码逻辑,而且完全可以进行测试。

比如我们通过  proc-macro2  编写了生成  proc_macro2::TokenStream  代码之后,再通过  proc_macro2::TokenStream::from(proc_macro::TokenStream)  转换成  proc_macro::TokenStream

见上面例子

标签:
    暂无数据