以前有基友说写的不够看,因此今天特地加餐说一下宏。以前的案例中有提到过可使用println!
宏进行打印。今天咱们就简单来讲说有关宏的几个方面:编程
宏其实就是咱们一般所谓的元编程,在rust中使用宏来扩展生成比咱们手写更多的代码。数组
你们应该知道元编程对于减小大量编写和维护的代码试很是有用的,但他又和函数有点区别,好比一个函数必需要声明它的参数个数和类型。可是宏只接受一个可变参数,并且能够在编译器翻译代码以前展开。这样就意味着咱们想要实现一个宏比定义函数更加复杂,也更难理解和维护。函数
同时在rust中宏定义没法出如今模块命名空间,并且必需要在调用以前定义或者将其导入,而函数则能够在任意地方。翻译
咱们可使用macro_rules!
来定义宏,这在Rust中使用的比较普遍。接下来咱们介绍一下vector,这是rust中的一种集合类型。和数组不同的是他存储在堆上,并且长度是动态增加的。并且vector是std中用泛型实现的,数组是原生内建的类型。具体有关vector的咱们暂时不展开,咱们只须要了解到可使用vec!
来生成一个给定值的vector。如:code
let v: Vec<i32> = vec![1, 2, 3];
而后咱们移步vec!
的实现,这是简化过的定义:编译器
#[macro_export] macro_rules! vec { ( $( $x:expr ),* ) => { { let mut temp_vec = Vec::new(); $( temp_vec.push($x); )* temp_vec } }; }
首先咱们看到的是一个注解,这个说明了该宏是可用的。而后macro_rules!
定义了名字vec后面跟上大括号。而后就是( $( $x:expr ),* )
,这句也就是一个模式(pattern),若是模式匹配了后面的相关代码就会执行。这和后面要说的match表达式的结构相似。而后,一对括号包含了所有模式。接下来是后跟一对括号的美圆符号( $ ),其经过替代代码捕获了符合括号内模式的值。$() 内则是 $x:expr ,其匹配 Rust 的任意表达式或给定 $x 名字的表达式。编译
$() 以后的逗号说明一个逗号分隔符能够有选择的出现代码以后,这段代码与在 $() 中所捕获的代码相匹配。紧随逗号以后的 说明该模式匹配零个或多个 以前的任何模式。泛型
因此当 vec![1, 2, 3]; 调用宏时,$x 模式与三个表达式 一、2 和 3 进行了三次匹配。扩展
就此打住,否则再讲下去打字员也是一脸懵逼了。命名空间
在rust中第二种形式的宏叫作过程式宏。接收rust代码做为输入,而后在代码上进行操做产生另一些代码输出。因为篇幅较长并且打字员也须要补补课因此咱们下次再介绍。
看到这里,你们是否是回忆起了C语言中的宏,种个草慢慢去研究趴。