Rust Macro
Table of Contents
1. Rust Macro
1.1. Basic Macro
macro_rules! test {
(`patten`) => {`template`};
(`patten`) => {`template`};
}
patten 示例:
$v:expr test: $v:expr $v:tt $v:ident
template 示例:
println!("{:?}",$v}
完整的例子:
macro_rules! print_n_times { ($n:expr, $v:expr) => ( for i in 0..$n { println!("{:?}", $v); } ); } fn main() { print_n_times!(3, "hello"); }
hello
1.2. Repetition
macro_rules! my_vec { ($($v:expr), *) => ( { let mut ret = vec![]; $( ret.push($v); )*; ret } ); ($($v:expr) *) => ( { let mut ret = vec![]; $( ret.push($v) );*; ret } ); } fn main() { println!("{:?}", my_vec!(1, 2, 3)); println!("{:?}", my_vec!(1 2 3)); }
[1, 2, 3] [1, 2, 3]
patten
patten 格式 `\((),*`, 表示重复 0 或 n 次, 以 `,` 间隔 patten 格式 `\)() *`, 表示重复 1 或 n 次, 以 ` ` 间隔
template
`\((X)*` 表示 X 输出多次 `\)(X);*` 表示 X 输出多次且以 `;` 间隔
1.3. Recursion
macro_rules! print { (one) => { println!("{:?}", 1); }; (two) => { println!("{:?}", 2); }; ($($v:tt),*) => { $( print!($v); )* }; } fn main() { print!(one, two, one); }
macro_rules! v { (None) => { println!("{:?}", "None"); }; ($v:expr) => { println!("{:?}", $v); }; ($($v:tt),*) => { println!("{:?}", "begin"); $( v!($v); )*; println!("{:?}", "end"); }; } fn main() { v![1, 2, None]; }
1.4. Built-In Macro
1.4.1. file!
1.4.2. line!
1.4.3. column!
1.4.4. stringify!
1.4.5. include!
1.4.6. include_str!
1.4.7. include_bytes!
1.5. Debug Macro
1.5.1. trace_macros!(true)
1.6. Fragment
expr
expression 是最常用的 fragment, 但它只能匹配表达式, 例如 1, "hello", 变量等,
tt
token tree, 如果想匹配一个不存在的符号, 可以使用 tt, 例如前面 recursion 例子中的 None, one, two 等.
ident
identifier
block
block, 例如
ty
type
- …