Rust基础学习-Rust宏

Rust中的宏是生成另一段代码的一段代码。可以根据输入生成代码,简化重复模式,使得代码更加简洁。比如我们一直在用的println!,vec!,panic!都是宏。


创建宏

可以使用macro_rules!创建一个宏:

rust 复制代码
macro_rules! macro_name {
    (...) => {...}
}

这里的() => {}是宏规则条目,我们可以在单个宏中匹配很多规则。

下面的宏将实现打印一个Hello World!:

rust 复制代码
macro_rules! hello_world {
    () => {
        println!("hello world!");
    };
}

fn main() {
    hello_world!()
}

带参数的宏

宏也可以接受参数,这使我们能够根据不同的输入定制生成的代码。例如,这是一个定义函数以打印自定义消息的宏:

rust 复制代码
macro_rules! print_msg {
    ($message:expr) => {
        println!("{}", $message)
    };
}

fn main() {
    print_msg!("helllo Rust");
}

在这里,创建了一个名为 print_message 的宏,它接受一个参数 message。宏的参数使用美元符号 进行前缀,并用设计器进行类型注释。Rust 将尝试匹配在匹配规则中定义的模式。在上面的例子中,我们的规则是:

rust 复制代码
($message:expr) => {
    println!("{}", $message)
};

在分号后面的部分:被称为标识符,这些是我们可以选择匹配的类型。在示例中,我们使用表达式标识符(expr)。

在这个例子中 m e s s a g e message message被赋值为hello Rust,然后传递到println!({},$message);

注意:在宏规则体内,我们可以使用许多设计ators

  • stmt:一个语句
  • pat:一个模式
  • expr:一个表达式
  • ty:一个类型
  • ident:一个标识符

Rust中的重复

当我们需要生成重复的代码时,Rust 宏也非常有用。我们可以定义一个宏来接受参数,并根据这些参数重复生成的代码。

macro_rules!支持使用$(...)*语法进行重复。括号内的...可以是任何有效的Rust表达式或模式。

rust 复制代码
macro_rules! repeat_print {
    ($($x:expr),*) => {
        $(
        println!("{}",$x);
        )*
    };
}
fn main() {
    repeat_print!(1, 2, 3, 4, 5, 6);
}

在这里,宏 repeat_print 接受一个参数,($($x:expr),*),这是一个重复的模式。

该模式由零个或多个表达式组成,用逗号分隔,这些表达式由宏匹配。在末尾的星号( * )符号将反复匹配 $()中的模式。

  • 在大括号内的代码 println!({}, x); ,根据宏定义的主体中 (...)* 的包装,会重复零次或多次,每次对参数列表中的表达式执行一次。
  • 代码中的 $x 指的是匹配的表达式。 生成的代码的每次迭代都将打印不同的表达式。
  • 现在,当我们调用 repeat_print!(1, 2, 3); 时,宏将生成这段代码:
rust 复制代码
println!("{}", 1); // matches argument 1,
println!("{}", 2); // matches argument 2,
println!("{}", 3); // matches argument 3

因此,这个宏 repeat_print! 能够以简洁和便捷的方式打印多个表达式,而无需每次都编写println!宏。


相关推荐
Gofarlic_oms15 小时前
利用API实现ANSYS许可证管理自动化集成
运维·服务器·开发语言·matlab·自动化·负载均衡
AI+程序员在路上6 小时前
VS Code 完全使用指南:下载、安装、核心功能与 内置AI 编程助手实战
开发语言·人工智能·windows·开源
invicinble6 小时前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
catchadmin7 小时前
使用 PHP TrueAsync 改造 Laravel 协程异步化的可行路径
开发语言·php·laravel
wbs_scy7 小时前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
stm32 菜鸟7 小时前
nucleo-f411re学习记录-12,Wifi模块ESP8684
学习
AI人工智能+电脑小能手7 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
郑州光合科技余经理8 小时前
同城O2O海外版二次开发实战:从支付网关到配送算法
开发语言·前端·后端·算法·架构·uni-app·php
stm32 菜鸟9 小时前
nucleo-f411re学习记录-9,双轴XY摇杆传感器
学习
南子北游9 小时前
Python学习(基础语法1)
开发语言·python·学习