Rust 1.7.0的macro宏-语法分析和使用举例
来源:互联网 发布:韩国整容 知乎 编辑:程序博客网 时间:2024/06/06 03:04
macro 宏的概念在很多语言中都有。
通常情况下,宏的机制是在预编译阶段对已经定义的宏进行替换或者 expanded 展开 ,即:把宏按照名称替换成宏的内容。
Rust 中的宏,与众不同!
Rust中的宏,也是在预编译阶段进行处理。宏不仅仅是替换内容和展开,还可以像功能函数一样,接收参数、调用其他的宏。
一、简单的宏
宏的名称和功能函数名称很像,只不过在函数名称后面有一个叹号!
一个简单的宏定义和调用:
macro_rules! say_hello{ ()=>( println!("Hello"); ) } fn main(){ say_hello!() }
解释一下:
macro_rules! 声明一个宏,say_hello 是宏的名字,say_hello后面是一对大括号,是宏的内容体。
大括号里面的=>前面的 ( ) 表示这个宏没有输入参数。
在这个宏内部,调用了另外一个宏 println!
在main()功能函数中调用宏。因为这个宏和调用的功能函数在一个文件中,所以不需要额外的导出和引入宏的声明。
当然,宏的内容体除了用 {}大括号之外,还可以使用 (); 和 [];
macro_rules! say_hello ( ()=>( println!("Hello"); ) );
macro_rules! say_hello [ ()=>( println!("Hello"); ) ];
⚠ 注意:
- 使用大括号的时候,大括号后面没有分号;
- 而使用()和[]的时候,后面有一个分号。
❌如果大括号{}有分号;或者()和[]没有分号都会编译错误。
⚠ 注意:
另一个需要注意的是,宏的输入参数是包含在宏内容体内的!!!
二、带参数的宏
下面定义一个带参数的宏 print_hello
macro_rules! print_hello{ ($msg:expr) =>( println!("hello{}", $msg); )}fn main(){ print_hello!(",world!");}
上面定义了一个 print_hello 宏,把上面的代码分解成 4 个部分:
第一个部分:宏声明
macro_rules! print_hello
- macro_rules! 是宏定义关键字,注意后面有 ! 叹号
- 后面跟宏的名称 这是定义宏的名称
第二部分:宏的内容边界 {一对大括号}
macro_rules! print_hello {}
第三部分:宏的内容 -大括号中的内容
大括号中的内容被称为 macro rule 宏规则。一个宏可以包含任意(0 -n)多个 macro rule 宏规则。
($msg:expr) =>( println!("hello{}", $msg) );($msg:expr) =>{ println!("hello{}", $msg) };($msg:expr) =>[ println!("hello{}", $msg) ];($msg:expr) => ( println!("hello{}", $msg); );($msg:expr) => { println!("hello{}", $msg); };($msg:expr) => [ println!("hello{}", $msg); ];
以上 6 句 作用完全一致!
宏规则的格式应该是这样的:
( ) => { };( ) => [ ];( ) => ( );
- 每个宏规则有一个 => ;
- 在 => 左面的小括号是该规则的输入参数,里面的形式是一个 叫做 matcher 匹配器;
- 在 => 右面的括号里是宏的内容,需要被执行或者替换,叫做 transcriber 转换器,可以是语句、表达式等。
以上三行代码等同。
matcher 和 transcriber 会在 后面的文章中详细说明。
前面说过,宏的参数是包含在宏内容体内的!
对比一下功能函数的声明格式:
fn fn_name(x:i32,y:u32){ }
功能函数的输入参数通过 fn_name 后面的小括号传入,参数可能是 0 个或者多个,但是所有的参数一定是在这个括号中声明。
来看看这段代码:
macro_rules! foo { (x => $e:expr) => (println!("mode X: {}", $e)); (y => $e:expr) => (println!("mode Y: {}", $e));}fn main() { foo!(x => 7); foo!(y => 3);}
宏的输入不是通过参数列表传入的!而是通过 match 的方式进行查找或者匹配的。
当匹配到 x => 7 ,则执行 mode X: 7
当匹配到 y => 3 ,则执行 mode Y: 3
第四部分:宏调用
print_hello!(",world!");
调用方式,使用宏名称后面加!叹号,叹号后面跟一个括号表示输入参数。
- Rust 1.7.0的macro宏-语法分析和使用举例
- Rust 的安装和使用举例
- Rust 1.7.0 macro宏的复用 #[macro_use]的用法
- FreeMarker macro(宏)的使用
- Freemaker <#macro>(宏)的使用
- freemarker macro(宏)的使用
- freemarker macro(宏)的使用
- FreeMarker宏macro的使用
- freemarker macro(宏)的使用
- FreeMarker宏macro的使用
- FreeMarker宏macro的使用
- freemarker macro(宏)的使用
- FreeMarker宏macro的使用
- freemarker macro(宏)的使用
- Rust 1.7.0 匹配器 match 的简单介绍和使用
- rust实现《一个典型的生产者和消费者的题目和实现》和rust使用感想
- iOS Macro的使用
- Rust 1.7.0 使用#[test]做单元测试
- 【优先队列】HDU1434幸福列车
- bzoj 4196: [Noi2015]软件包管理器
- 利用excel办公软件快速拼凑sql语句
- ListView如何滚动和恢复到某个位置
- OC篇学习-数组
- Rust 1.7.0的macro宏-语法分析和使用举例
- 算法浅谈:从KNN算法谈起
- Canvas开篇之drawBitmap方法讲解
- Android之Activity框架
- Android生成二维码
- Android数据库加密
- missing ';' before identifier 'PVOID64'
- 初识 js Cookies
- POJ【1661】Help Jimmy