rust 宏 - tycoon3

rust 宏

Rust 中的属性,可以分为以下四大类。

  1. Macro attributes - 宏属性
  2. Derive macro helper attributes - 派生宏辅助属性
  3. Tool attributes - 工具属性
  4. Built-in attributes - 内建属性

Macro Attributes 宏属性

宏属性,也叫属性宏。属于过程宏的一种。

定义过程宏的时候,使用 #[proc_macro_attribute],加一个固定签名的函数(详见过程宏一章)。

#[proc_macro_attribute]
pub fn return_as_is(_attr: TokenStream, item: TokenStream) -> TokenStream {
        item
}

使用过程宏:

#[return_as_is]
fn invoke() {}

Derive macro helper attributes 派生宏辅助属性

派生宏辅助属性,听起来有点拗口,其实它是这样一个东西:

先定义派生宏

#[proc_macro_derive(HelperAttr, attributes(helper))]
pub fn derive_helper_attr(_item: TokenStream) -> TokenStream {
TokenStream::new()
}

看如何使用:

#[derive(HelperAttr)]
struct Struct {
        #[helper] field: ()
}

里面那个 #[helper] 就是一个派生宏辅助属性。

Tool Attributes 工具属性

工具属性。Rust 还允许外部工具定义它们自己的属性,并且在独立的命名空间下面。比如:

// Tells the rustfmt tool to not format the following element.
#[rustfmt::skip]
struct S {
}

// Controls the "cyclomatic complexity" threshold for the clippy tool.
#[clippy::cyclomatic_complexity = "100"]
pub fn f() {}

不过如果你想在自己的工具中定义 Tool Attribute,那就想多了。现在 rustc 只认识两个外部工具(及它们内部的属性):一个是 rustfmt,另一个是 clippy。

macro_rules! calculate {
    (eval $e:expr) => {{
        {
            let val: usize = $e; // Force types to be integers
            println!("{} = {}", stringify!{$e}, val);
        }
    }};
}

fn main() {
    calculate! {
        eval 1 + 2 // hehehe `eval` is _not_ a Rust keyword!
    }

    calculate! {
        eval (1 + 2) * (3 / 4)
    }
}
[root@bogon macro1]# cargo build
   Compiling own v0.1.0 (/data2/rust/macro1)
    Finished dev [unoptimized + debuginfo] target(s) in 0.41s
[root@bogon macro1]# cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/own`
1 + 2 = 3
(1 + 2) * (3 / 4) = 0