目录
什么是 Rust 宏
Rust 宏 (Macros) 是一种元编程工具,允许在编译时生成代码。它们扩展了语言的语法,提供比函数更灵活的代码生成能力,主要分为声明式宏和过程宏。
为什么要使用宏
- 代码复用:减少重复代码。
- 语法扩展:创建特定领域的语法。
- 性能:编译时展开,无运行时开销。
- 灵活性:处理可变参数或复杂逻辑。
宏的类型
- 声明式宏 (Declarative Macros):
- 使用
macro_rules!
定义。 - 基于模式匹配,类似函数但更强大。
- 过程宏 (Procedural Macros):
- 三种形式:自定义派生、属性宏、函数式宏。
- 操作抽象语法树 (AST),需单独 crate。
- 依赖
proc-macro
库。
声明式宏的定义与使用
- 定义:
macro_rules! name { (模式) => { 展开代码 } }
。 - 模式匹配:
$var:类型
:捕获变量(类型如expr
、ident
)。*
或+
:匹配零个或多个。- 调用:
name!(参数)
。
macro_rules! say_hello {
() => {
println!("Hello!");
};
}
过程宏简介
- 自定义派生 (Derive):为结构体/枚举自动实现特性(如
Debug
)。 - 属性宏:修改项的定义。
- 函数式宏:类似函数的宏。
- 限制:需在单独 crate 中定义,依赖
proc-macro
。
[lib]
proc-macro = true
代码示例
声明式宏
macro_rules! vec_of {
($($x:expr),*) => {
{
let mut v = Vec::new();
$(v.push($x);)*
v
}
};
}
fn main() {
let v = vec_of![1, 2, 3, 4];
println!("{:?}", v);
}
运行结果:
[1, 2, 3, 4]
多模式声明式宏
macro_rules! greet {
($name:expr) => {
println!("Hello, {}!", $name);
};
($name:expr, $greeting:expr) => {
println!("{}, {}!", $greeting, $name);
};
}
fn main() {
greet!("Alice");
greet!("Bob", "Hi");
}
运行结果:
Hello, Alice!
Hi, Bob!
简单过程宏(自定义派生)
my_macro/Cargo.toml
:
[package]
name = "my_macro"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
syn = “2.0” quote = “1.0” proc-macro2 = “1.0”
my_macro/src/lib.rs
:
use proc_macro::TokenStream;
use quote::quote;
use syn;
#[proc_macro_derive(Hello)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();
impl_hello(&ast)
}
fn impl_hello(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let gen = quote! {
impl #name {
pub fn say_hello(&self) {
println!("Hello from {}", stringify!(#name));
}
}
};
gen.into()
}
主项目 Cargo.toml
:
[dependencies]
my_macro = { path = "./my_macro" }
main.rs
:
use my_macro::Hello;
#[derive(Hello)]
struct Example;
fn main() {
let ex = Example;
ex.say_hello();
}
运行结果:
Hello from Example
参考资料与出站链接
- 官方文档:
- 学习资源:
- 社区支持:
发表回复