最近在学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代码中添加属性宏的代码:
属性宏难度比较大,需要好好琢磨
