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

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.dtcms.com/a/324122.html

相关文章:

  • WPFC#超市管理系统(5)商品布局、顾客登录、商品下单
  • redis集群-docker环境
  • JAVA+AI简化开发操作
  • `sk_buff` 结构体详解(包含全生命周期解析)
  • How Websites Work 网站如何运作
  • 社交与职场中的墨菲定律
  • 2025年6月电子学会全国青少年软件编程等级考试(Python三级)真题及答案
  • DBAPI 实现不同角色控制查看表的不同列
  • 量子计算机实用化:从理论到现实的艰难跨越
  • 数据中心可视化:算力中枢智能运维
  • 编程基础之字符串——统计数字字符个数
  • JDBC的连接过程(超详细)
  • 【Docker-Day 12】揭秘容器网络:深入理解 Docker Bridge 模式与端口映射
  • Python爬虫-爬取政务网站的文档正文内容和附件数据
  • 【Linux | 网络】数据链路层
  • 电脑清理3步速成法
  • 三相LLC拓扑分析
  • CompletableFuture实现Excel sheet页导出
  • 产品经理入门 - 产品解决方案(需求分析、 功能优先级划分、功能价值、用户体验)
  • RabbitMQ面试精讲 Day 19:网络调优与连接池管理
  • NLP---IF-IDF案例分析
  • AI编程插件对比分析:CodeRider、GitHub Copilot及其他
  • 构建企业级Odoo 18 WMS——功能、架构与拓展蓝图
  • 宝塔面板部署sentinel
  • 【传奇开心果系列】基于Flet框架开发的增强版“Hello World“应用程序学习flet框架的拔高起点
  • 【后端】Java 8 特性 `User::getId` 语法(方法引用)介绍
  • Linux常用命令(后端开发版)
  • SQL(结构化查询语言)的四大核心分类
  • 【后端】Java 8 特性 Optional 可选类 介绍
  • Oracle 19C 查看卡慢的解决思路