最近在学rust宏宏,所以就记录一下,发现rust的宏功能非常强大
声明宏
宏定义的语法:
macro_rules! macro_name {
// 宏定义体 模式匹配
()=>{}
}
// 宏定义的例子:
//比如写一个创造结构体的宏
macro_rules! create_struct {
($name:ident, $field_type:ty) => {
struct $name {
field: $field_type,
}
}
}
//使用宏定义
create_struct!(MyStruct, i32);
//创建结构体
let my_struct = MyStruct { field: 42 };
// 写一个hashmmap宏
macro_rules! hashmmap {
// 空HashMap
() => {
{
std::collections::HashMap::new()
}
};
// 带键值对的HashMap
($($key:expr => $val:expr),+ $(,)?) => {
{
let mut map = std::collections::HashMap::new();
$(
map.insert($key, $val);
)+
map
}
};
}
// 使用宏定义
let empty_map = hashmmap!();
//写一个创建函数的宏
macro_rules! create_fn {
($name:ident,$ret:ty)=>>{
fn $name()->$ret {
return $ret;
}
}
}
create_fn!(add,i32);
//大致就这样
rust声明宏用到的参数
宏定义的参数有:
| 片段分类符 | 含义与用途 | 代码示例 |
|———–|———–|———|
| ident
| 标识符或关键字 | 变量名、函数名、模块名等 如: x
, my_function
|
| expr
| 表达式 | 2 + 2
, x
, function_call()
|
| ty
| 类型 | i32
, String
, Vec<u8>
, MyStruct
|
| pat
| 模式(用于模式匹配) | Some(x)
, _
, Point { x, y }
|
| stmt
| 语句 | let x = 5;
, println!();
|
| block
| 块表达式(由花括号包围的语句和表达式序列) | { let x = 5; x + 10 }
|
| item
| 程序项(包含函数、结构体、模块等) | fn foo() {}
, struct Bar;
|
| meta
| 元数据(属性内部的内容) | derive(Debug)
, cfg(target_os = "linux")
|
| tt
| 标记树(单个标记或由定界符包围的标记组) | 几乎任何标记序列,通用性强 |
| lifetime
| 生命周期参数 | 'a
, 'static
|
| vis
| 可见性限定符 | pub
, pub(crate)
|
| literal
| 字面量 | 42
, "hello"
, 3.14
, 'c'
|
| path
| 类型表达式中的路径 | std::vec::Vec
, super::Module::Type
|
大致就这些,一般expr和ty还有ident常用
属性宏
属性宏,也叫属性宏,是一种用于扩展Rust语言的宏。属性宏允许用户定义一个宏,该宏可以在Rust代码中的任何地方使用,并添加额外的功能。属性宏通常用于扩展Rust代码,如添加注释、检查代码质量、生成代码等。
属性宏是单独crate引入的,所以需要单独创建一个crate
cargo new my_attr_crate --lib
创建好crate后,在crate的Cargo.toml中添加属性宏的依赖:
//一般是添加三个依赖
[dependencies]
proc-macro2 = "1.0.26"
syn = "1.0.86"
quote = "1.0.9"
[lib]
//设置为属性宏
proc-macro = true
# 在lib代码中添加属性宏的代码:
属性宏难度比较大,需要好好琢磨