Rust中的声明宏和过程宏

宏是Rust语言中的一个重要特性,它允许开发人员编写可重用的代码,以便在编译时扩展和生成新的代码。宏可以帮助开发人员减少重复代码,并提高代码的可读性和可维护性。Rust中有两种类型的宏:声明宏和过程宏。

声明宏:

声明宏是一种用于定义新的宏的语法。它使用macro_rules!关键字定义,并遵循特定的语法规则。声明宏通常用于定义简单的宏,例如计算两个数字之和或打印一条消息。

例如,下面是一个简单的声明宏,用于计算两个数字之和:

macro_rules! add {
($x:expr, $y:expr) => {
$x + $y
};
} fn main() {
let x = 5;
let y = 6;
println!("{}", add!(x, y));
}
复制代码

在上面的示例中,我们定义了一个名为add的声明宏。该宏接受两个参数:$x$y,并使用=>符号将参数映射到表达式$x + $y。在主函数中,我们使用add!(x, y)调用该宏,并将结果打印到控制台。

过程宏:

过程宏是另一种用于定义新的宏的语法。与声明宏不同,过程宏使用特殊的函数来定义,并可以接受任意数量的参数。过程宏通常用于定义更复杂、更强大的宏,例如实现自定义派生或生成新的类型。

例如,下面是一个简单的过程宏,用于计算两个数字之和:

use proc_macro::TokenStream;

#[proc_macro]
pub fn add(input: TokenStream) -> TokenStream {
let mut iter = input.into_iter();
let x = iter.next().unwrap();
let _comma = iter.next().unwrap();
let y = iter.next().unwrap(); let result = format!("{} + {}", x, y);
result.parse().unwrap()
} fn main() {
let x = 5;
let y = 6;
println!("{}", add!(x, y));
}
复制代码

在上面的示例中,我们定义了一个名为add的过程宏。该函数使用#[proc_macro]属性标记,并接受一个名为input的参数。该参数表示传递给该宏的TokenStream。在函数体内部,我们使用迭代器来访问TokenStream中的每个元素,并使用format!宏将其格式化为字符串。最后,我们将结果转换为TokenStream并返回。

声明宏和过程宏的比较:

声明宏和过程宏都可以用于定义新的宏,但它们之间存在一些差异。声明宏更简单、易于使用,但功能有限;而过程宏更强大、灵活,但需要更多的编码技巧。

例如,在上面给出的示例中,我们可以看到声明宏和过程宏都可以用于计算 两个数字之和。但是,声明宏只能接受固定数量的参数,并且必须遵循特定的语法规则。而过程宏则可以接受任意数量的参数,并且可以使用任意的Rust代码来定义宏的行为。

此外,声明宏和过程宏在实现方式上也有所不同。声明宏是在编译时扩展的,这意味着它们在编译器内部被处理。而过程宏则是在编译时调用的,这意味着它们在编译器外部被处理。这种差异使得过程宏可以访问更多的编译器信息,并且可以使用更复杂的算法来生成新的代码。

结论:

总之,Rust中的宏是一种强大的工具,可以帮助开发人员编写可重用、高效和灵活的代码。无论是声明宝还是过程宝,都值得开发人员学习和掌握。通过使用宏,开发人员可以减少重复代码,并提高代码的可读性和可维护性。因此,如果您正在使用Rust语言进行软件开发,那么了解宏是非常重要的。from刘金,转载请注明原文链接。感谢!

Rust中的宏:声明宏和过程宏的更多相关文章

  1. Sass--混合宏--声明宏

    如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的.但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无法达到我们目了.这 ...

  2. 在 C++ 程序中只使用 const 常量而不使用宏常量

    在 C++ 程序中只使用 const 常量而不使用宏常量,即 const 常量完 全取代宏常量. #include <iostream> /* run this program using ...

  3. 编写Java程序,模拟五子棋博弈过程中的异常声明和异常抛出

    返回本章节 返回作业目录 需求说明: 模拟五子棋博弈过程中的异常声明和异常抛出,判断用户所下棋子的位置,是否超越了棋盘的边界. 棋盘的横坐标的范围为0-9,纵坐标范围为0-14,如果用户所放棋子的坐标 ...

  4. 刷完欧拉计划中难度系数为5%的所有63道题,我学会了Rust中的哪些知识点?

    我为什么学Rust? 2019年6月18日,Facebook发布了数字货币Libra的技术白皮书,我也第一时间体验了一下它的智能合约编程语言MOVE,发现这个MOVE是用Rust编写的,看来想准确理解 ...

  5. C++中的inline声明

    C++中的inline声明 1. inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把函数指定为内联函数. inline int min(i ...

  6. 嵌入式C语言自我修养 12:有一种宏,叫可变参数宏

    12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后, ...

  7. 宏定义(无参宏定义和带参宏定义),C语言宏定义详解

    1.宏定义说明 宏定义是比较常用的预处理指令,即使用"标识符"来表示"替换列表"中的内容.标识符称为宏名,在预处理过程中,预处理器会把源程序中所有宏名,替换成宏 ...

  8. Rust 中的类型转换

    1. as 运算符 as 运算符有点像 C 中的强制类型转换,区别在于,它只能用于原始类型(i32 .i64 .f32 . f64 . u8 . u32 . char 等类型),并且它是安全的. 例 ...

  9. 【译】理解Rust中的Futures (一)

    原文标题:Understanding Futures In Rust -- Part 1 原文链接:https://www.viget.com/articles/understanding-futur ...

  10. Rust 中的继承与代码复用

    在学习Rust过程中突然想到怎么实现继承,特别是用于代码复用的继承,于是在网上查了查,发现不是那么简单的. C++的继承 首先看看c++中是如何做的. 例如要做一个场景结点的Node类和一个Sprit ...

随机推荐

  1. Windows使用技巧(持续更新)

    如何将应用添加到鼠标右键菜单? 1. Win+R  输入:regedit打开注册表 2. 找到HKEY_CLASSES_ROOT\Directory\Background\shell,在该路径下创建项 ...

  2. linux命令基本操作

    chmod 命令 : chmod -R 755 tools_command/ 解释 : -R 为递归遍历tools_command文件夹, chmod 755修改权限: 查看所有用户 1.cat /e ...

  3. The Ultimate Guide to Dynamics 365 Pricing and Licensing

        Microsoft Dynamics 365 integrates powerful ERP and CRM capabilities in the cloud to provide busi ...

  4. awk sub string

    cat TFY1C.txt|awk '{print $0"\t"substr($4,1,4)}'> TFY1CRID.tx 1--从那位开始 4--多长

  5. centos 添加yum源失败,ping 百度没响应

    1. curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.r ...

  6. RabbitMQ service does not start due to corrupted mnesia database in RSA Security Analytics

    rabbitmq异常:mnesia database损坏

  7. Codeforces Round #803 (Div. 2) A-D 刚vp完还没补题

    Codeforces Round #803 (Div. 2) 2022/7/24 上午VP 传送门:https://codeforces.com/contest/1698 A. XOR Mixup 随 ...

  8. 使用ASP.NET Core开发信息采集系统将用户数据添加至企业微信

    一.启动Visual Studio 2019,创建ASP.NET Core Web应用程序 二.在Models文件夹添加新项 Person.cs using System.ComponentModel ...

  9. spring-boot-starter-webflux

    webflux: 反应式编程reactor的产物,采用发布订阅模式,引入netty的nio,比较适合IO密集型应用. 因普遍应用使用的DB链接是IO阻塞型,因此在一般应用中无法体现它的优势.redis ...

  10. k8s 关于pull image failed 问题

    问题描述: Failed to pull image "nginx": rpc error: code = Unknown desc = failed to pul 解决办法: 1 ...