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

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

前置知识点

各种宏

  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

题目

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

// macros1.rs
//
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    };
}

fn main() {
    my_macro();
}

题解
macro_rules! my_macro {
    () => {
        println!("Check out my macro!");
    };
}

fn main() {
    my_macro!();
}

macros2

题目

在宏的定义中使用了

// 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 DONE

mod macros {
    macro_rules! my_macro {
        () => {
            println!("Check out my macro!");
        };
    }
}

fn main() {
    my_macro!();
}

题解

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

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

fn main() {
    my_macro!();
}

marcros3

题目
// 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);
}

题解

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

// 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.kler.cn/news/364442.html

相关文章:

  • uni-app 开发微信小程序,实现图片预览和保存
  • QImage和QPixmap
  • GO excelize 读取excel进行时间类型转换(自动转换)
  • vuetify页面布局
  • 【WRF数据处理】基于GIS4WRF插件将geotiff数据转为tiff(geogrid,WPS所需数据)
  • 基于SSM+小程序的就业管理系统(就业1)
  • [Linux网络编程]04-多进程/多线程并发服务器思路分析及实现(进程,信号,socket,线程...)
  • C# 委托简述
  • ifconfig 和 ip addr
  • jmeter中csv data set config的Sharing mode和loop控制器结合使用
  • 重修设计模式-行为型-访问者模式
  • Github + 自定义域名搭建个人静态站点
  • TensorFlow面试整理-TensorFlow 结构与组件
  • Python Web 框架中 Django 框架
  • Scrapy | 通过爬取豆瓣Top250电影信息来学习在中间件中应用随机请求头和代理ip
  • C++:排序算法
  • Spring Cloud --- GateWay和Sentinel集成实现服务限流
  • pycharm中使用ctrl+鼠标滚轮改变字体大小
  • 微积分复习笔记 Calculus Volume 1 - 3.6 The Chain Rule
  • 直觉微调——简化语言模型对齐过程
  • opencv学习笔记(4):图像属性和基本图形绘制
  • 【纯血鸿蒙】HarmonyOS和OpenHarmony 的区别
  • 【LInux】Shell脚本编写基本语法
  • 快速获取 GitHub 个人资料成就徽章
  • LinkedList 源码分析
  • 数据清洗的具体方法有哪些?