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. nodejs <a>带参数返回路由标记执行数据库操作

    今天在测试mongo数据库操作维护的时候,测试了一下直接在表内添加操作列来完成数据的删除操作,直接返回数据库ID,页面表格如下: 通过点击删除,即可完成对应条目数据库删除操作. 1.mongo数据操作 ...

  2. What is RSS

    What is RSS?RSS (Rich Site Summary) is a format for delivering regularly changing web content. Many ...

  3. ABP vNext微服务架构详细教程(补充篇)——单层模板

    1. 简介 在之前的<ABP vNext微服务架构详细教程>系列中,我们已经构建了完整的微服务架构实例,但是在开发过程中,我们会发现每个基础服务都包含10个类库,这是给予DDD四层架构下A ...

  4. HPA 弹性伸缩

    在k8s中,我们使用pod对外提供服务,这个时候,需要以下两种情形需要关注: pod因为不明原因挂掉,导致服务不可用 pod在高负载的情况下,不能支持我们的服务 如果人工监控pods,人工调整副本,那 ...

  5. StatefulSet 模板,更新,扩缩容,删除

    概念: StatefulSet是用来管理有状态应用的工作负载API对象,kubectl 中可以简写sts ,sts每一个pod生成一个唯一的标识符,sts_name-number,number从0开始 ...

  6. 子接口vlan终结

    问题: 在华为的NE40E设备上,配置三层字接口的ip后,接口的physical状态为up, protocol为down,接口还是不可用. 解决方案: 需要在子接口上配置vlan终结,配置如下: 为什 ...

  7. .DS_Store泄露利用过程

    .DS_Store文件泄漏利用工具: ds_store_exp.DS_Store是Mac下Finder用来保存如何展示 文件/文件夹 的数据文件,每个文件夹下对应一个. 如果开发/设计人员将.DS_S ...

  8. mysql根据一个表更新另外一个表

    -- 语法:update table_1 t1,table_2 t2 set t1.column = t2.column where t1.id = t2.pid; UPDATE house_test ...

  9. AreEngine 求最小面积的外接矩形,非IEnvelope,表达不清楚了

    1,总是会得到一些奇奇怪怪的要求,求一个面对象的外接最小面积的矩形,和ArcToolBox中的Mininum Bounding Geometry功能下的RECTANGLE_BY_AREA想似.具体看下 ...

  10. 2022安洵杯pwn-babyarm

    首先就是绕过一个简单的变表base64的加密key 然后就是一个类似ret2libc的利用方式,不过没有直接控制r0的gadget 使用的是arm32中万能的gadget from pwn impor ...