当前位置: 首页 > ops >正文

Rust进阶-part6-宏

Rust进阶[part6]_宏

macro 概述

宏是 Rust 中强大的代码生成工具,与函数不同,它在编译期展开并生成具体代码,能处理可变参数、实现动态逻辑,语法上以 ! 结尾(如 println! vec! panic!)。

常用宏简化了重复操作:println! 处理格式化输出,vec! 快速创建向量,cfg! 做条件编译判断。宏支持模式匹配和代码生成,比函数更灵活,但也因编译期处理,调试和学习门槛稍高。按功能可分为声明宏(基于模式匹配)和过程宏(更复杂的代码生成),是 Rust 元编程的核心能力。

一些之前常用的宏,例如 println!vec! 等,它们简化了代码编写。

声明宏

声明宏允许你通过模式匹配来生成代码。例如,下面是一个简单的加法声明宏:

macro_rules! add {($a:expr, $b:expr) => {$a + $b};
}fn main() {let result = add!(1, 2);println!("Result: {}", result);
}

格式

macro_rules! 宏名称 {(模式1) => { 代码1 };(模式2) => { 代码2 };// ...
}
  • 模式:匹配调用宏时的输入参数。
  • 元变量:用 $ 开头,捕获输入的片段(如表达式、标识符等)。
  • 重复符号*(零或多次)、+(至少一次),类似正则表达式。

过程宏

派生宏

派生宏可以为结构体、枚举等类型自动生成代码。例如,使用 #[derive(Debug)] 可以自动为结构体添加调试输出的能力:

#[derive(Debug)]
struct Person {name: String,age: u8,
}fn main() {let person = Person {name: String::from("Alice"),age: 30,};println!("{:?}", person);
}

属性宏

属性宏可以为函数、结构体等添加自定义属性。例如,自定义一个日志属性宏:

#[proc_macro_attribute]
pub fn log(_attr: TokenStream, item: TokenStream) -> TokenStream {// 这里可以实现日志记录逻辑item
}#[log]
fn my_function() {println!("Function called");
}fn main() {my_function();
}

函数宏

函数宏类似于普通函数,但在编译时展开。例如:

#[proc_macro]
pub fn greet(_item: TokenStream) -> TokenStream {let code = "println!(\"Hello, world!\");";code.parse().unwrap()
}fn main() {greet!();
}

总结

宏是 Rust 中强大的代码生成工具,声明宏通过模式匹配生成代码,过程宏则提供了更灵活的代码生成方式,包括派生宏、属性宏和函数宏。

应用场景

  1. 减少重复代码: 通过宏生成重复的代码,提高代码的可维护性。
  2. 编译期计算:在编译器进行计算并生成代码,提高运行时性能。
  3. DSL(领域特定语言):使用宏定义领域特定语言,提高代码的表达力和可读性。

课后习题

实现一下宏

assert_eq!(repeat!("x", 3), "xxx");assert_eq!(sum!(1, 2, 3, 4, 5), 15);assert_eq!(max_value!(1, 8, 9), 9);

代码:

#[macro_export]
macro_rules! say_hello {() => {println!("hello!");};($name:expr) => {println!("hello {}!", $name);};
}#[macro_export]
macro_rules! repeat {() => {println!("repeat!");};($s:expr, $n:expr) => {std::string::String::from($s).repeat($n)};
}#[macro_export]
macro_rules! sum {() => {println!("sum!");};($($x:expr),*) => {{let mut total = 0;$(total += $x;)*total}};
}#[macro_export]
macro_rules! max_value {() => {println!("max_value!");};($x:expr, $y:expr, $z:expr) => {if $x > $y {if $x > $z { $x } else { $z }} else {if $y > $z { $y } else { $z }}};
}

一些符号拆解:

  • $():分组捕获元变量。
  • \*/+:重复匹配输入片段。
  • $(...)\*:在展开时代入重复的代码逻辑。
// sum! 宏展开逻辑
$(total += $x;)*  // 对每个捕获的表达式,生成一次累加语句
http://www.xdnf.cn/news/17458.html

相关文章:

  • LLaMA-Adapter V2 Parameter-Efficient Visual Instruction Model
  • Shell脚本-数组定义
  • Android 四大布局:使用方式与性能优化原理
  • ELK分布式日志采集系统
  • 手写 Spring
  • 《Go小技巧易错点100例》第三十七篇
  • 创建降阶模型用于搅拌槽中的涡流预测
  • 线性代数1000题学习笔记
  • 【机器学习深度学习】Embedding 模型详解:从基础原理到实际应用场景
  • NLP——TF-IDF算法
  • 《从零构建大语言模型》学习笔记4,注意力机制1
  • ADK(Agent Development Kit)【2】调用流程详解
  • 【东枫科技】 FR2 Massive MIMO 原型验证与开发平台,8*8通道
  • NLP学习开始-02逻辑回归
  • 【软件测试】性能测试 —— 工具篇 JMeter 介绍与使用
  • C++高频知识点(十九)
  • 【AI论文】LongVie:多模态引导的可控超长视频生成
  • 嵌套-列表存储字典,字典存储列表,字典存储字典
  • InfluxDB 在物联网设备数据采集与分析中的应用(一)
  • Python爬虫-爬取政务网站的文档正文内容和附件数据
  • 如何解决线上gc频繁的问题?
  • 在Ansys Simplorer中设计三相逆变器,并与Maxwell FEA耦合,实现160kW PMSM
  • Day 10: Transformer完整架构详解 - 从位置编码到编解码器的全面剖析
  • Excel常用功能函数
  • 重学React(四):状态管理二
  • 攻击者瞄准加密技术的基础:智能合约
  • Dify集成 Echarts 实现智能数据报表集成与展示实战详解
  • 第三章-提示词:从0到1,提示词实训全攻略,解锁大语言模型无限潜能(14/36)
  • 深度解析 Spring Boot 循环依赖:原理、源码与解决方案
  • Python vs MATLAB:智能体开发实战对比