【rCore OS 开源操作系统】Rust 宏

devtools/2024/10/21 19:16:50/

前置知识点

各种宏

  1. 宏定义:

使用 macro_rules! 关键词来定义宏,这是一种模式匹配式的宏定义方式。
自 Rust 1.26 版本开始,可以使用 proc_macro 属性宏来定义过程宏(如 derive 宏)。

  1. 宏的使用:

宏可以通过定义好的宏名来调用,宏调用时传入的参数会被宏定义中的模式匹配所捕获,并根据定义的规则生成相应的代码。

  1. 卫生宏(hygiene):

Rust 的宏支持卫生性,这意味着宏调用时的上下文信息会被保留下来,以避免命名冲突等问题。

  1. 模式匹配:

Rust 的宏支持模式匹配,这使得宏可以根据传入的不同参数生成不同的代码。

  1. 过程宏(procedural macros):

Rust 支持三种类型的过程宏:derive 宏、属性宏(attribute-like macros)和函数宏(function-like macros)。

  1. derive 宏允许用户为自定义类型添加默认的行为。
  2. 属性宏和函数宏允许用户定义更加复杂的代码生成逻辑。
  3. 宏的可见性和导入:
    宏可以通过 pub use 语句来导入到其他模块中。
    在 Rust 2018 版本之前,需要使用 #[macro_use] 来导入宏。但在 Rust 2018 版本之后,可以直接通过 use 语句来导入宏。

和函数的区别

在Rust中,宏定义(macros)和函数(functions)有以下区别:

  1. 语法:宏定义采用 macro_rules! 关键字进行定义,而函数使用 fn 关键字进行定义。

  2. 调用方式:宏定义使用 ! 运算符来调用,而函数使用圆括号 () 运算符来调用。

  3. 参数传递:宏定义可以接受任意数量的参数,并且可以使用模式匹配来匹配传递的参数,而函数需要明确指定参数的数量和类型。

  4. 代码生成:宏定义在编译期间进行代码生成,将宏展开为实际的代码,而函数在运行时执行。

  5. 功能扩展:宏定义可以执行复杂的代码转换和代码生成,可以在编译期间进行元编程,而函数只能执行预定义的操作。

总的来说,宏定义在编译期间进行代码生成和转换,具有更高的灵活性和功能扩展性,但也更加复杂和难以理解。函数则是在运行时执行,更加简单和直观。在选择宏定义和函数之间,需要根据具体的需求和场景来决定。

练习题

macros1

题目

考点:注意宏需要用!来定义。

rust">// macros1.rs
//
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
// hint.// I AM NOT DONEmacro_rules! my_macro {() => {println!("Check out my macro!");};
}fn main() {my_macro();
}
题解
rust">macro_rules! my_macro {() => {println!("Check out my macro!");};
}fn main() {my_macro!();
}

macros2

题目

在宏的定义中使用了

rust">// macros3.rs
//
// Make me compile, without taking the macro out of the module!
//
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
// hint.// I AM NOT DONEmod macros {macro_rules! my_macro {() => {println!("Check out my macro!");};}
}fn main() {my_macro!();
}
题解

在 Rust 2018 之前,对于不在同一个直接 mod 下的 macro,都需要加 #[macro_use] 后才能使用。

rust">#[macro_use]
mod macros {macro_rules! my_macro {() => {println!("Check out my macro!");};}
}fn main() {my_macro!();
}

marcros3

题目
rust">// macros4.rs
//
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint.// I AM NOT DONE#[rustfmt::skip]
macro_rules! my_macro {() => {println!("Check out my macro!");}($val:expr) => {println!("Look at this other macro: {}", $val);}
}fn main() {my_macro!();my_macro!(7777);
}
题解

其实就是考察宏可以重载:

rust">// macros4.rs
//
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint.#[rustfmt::skip]
macro_rules! my_macro {() => {println!("Check out my macro!");};($val:expr) => {println!("Look at this other macro: {}", $val);}
}fn main() {// 类似于一种重载my_macro!();my_macro!(7777);
}

http://www.ppmy.cn/devtools/127635.html

相关文章

SICK系列激光雷达单点测距仪DT80-311111+SIG200配置和通信

文章目录 一、硬件连接与SOPAS连接测距仪二、从SOPAS读取数据三、通过JSON获取数据1. 使用Postman测试接口2. 通过代码实现 一、硬件连接与SOPAS连接测距仪 首先硬件设备连接如下: 电源厂家应该是不提供,需要自行解决。 安装完成后需要使用sick的SOPAS…

Java爬虫:获取商品销量详情API返回值的实战指南

在数字化时代,数据已成为电商运营的核心。商品销量数据不仅反映了市场的需求和趋势,还能为商家提供决策支持。通过Java爬虫技术,我们可以高效地获取这些数据,从而深入分析商品的市场表现。 为何选择Java爬虫获取销量数据 自动化处…

13.3寸三防平板大尺寸+高速运行提升工业软件操作体验

在工业领域,移动设备的应用日益广泛,其性能直接影响着工作效率和数据安全。传统的工业平板电脑常常面临着屏幕尺寸过小、运行速度缓慢、以及抗环境能力不足等问题,这些都制约了工业软件的流畅运行和高效应用。而一款搭载先进硬件配置的13.3寸…

微信小程序/uniapp动态修改tabBar信息及常见报错

目录 uni.setTabBarItem(options)介绍:参数:示例: 报错 uni.setTabBarItem(options) 介绍: wx.setTabBarItem是不支持修改url路径的,所以使用uniapp的API。 动态设置 tabBar 某一项的内容:uniapp官网 se…

Sigrity-Power SI如何使用Model Extraction模式提取电源网络的S参数和阻抗操作指导(二)

Sigrity-Power SI如何使用Model Extraction模式提取电源网络的S参数和阻抗操作指导(二) Sigrity-Power SI如何查看电源网络的S参数和阻抗操作指导(一)结果中在74Mhz和720Mhz处出现较大的谐振。可以通过添加该谐振频率的电容来降低谐振峰值. 还是这块PCB,仅仅添加一些电容到PC…

Linux中device_create、device_add、device_register的区别

目录 前言: 一、源码分析 1、device_create() 2、device_register 3、device_add 二、device_create()、device_register()、device_add()使用中的区别 1、device_create() 2、device_register() 3、device_add() 前言: Linux设备驱动开发中&…

Maven与Gradle的区别

Maven与Gradle是两种流行的构建工具,广泛用于Java项目的管理和构建。以下是它们的对比,包括官网、Windows 11配置环境、在IDEA中的相同点和不同点,以及它们各自的优缺点。 官网 Maven官网: https://maven.apache.orgGradle官网: https://gr…

Docker基础操作

文章目录 一、安装Docker二、Docker镜像操作1.搜索镜像 docker search2.获取镜像 docker pull3.查看镜像信息 docker images4.获取镜像/容器 详细信息 docker inspect5.为本地的镜像添加新的标签 docker tag6.删除镜像 docker rmi7.将镜像保存成为本地文件 docker save -o8.将镜…