Rust 中的屬性,可以分為以下四大類。
- Macro attributes - 宏屬性
- Derive macro helper attributes - 派生宏輔助屬性
- Tool attributes - 工具屬性
- 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