rust lang的宏可能有些人学习比较困难,我自己也是花了很多时间才看懂,这里把认为最难理解的公布出来,希望让更多的人能够减少学习难度,更好的学习rust
首先在说明rust lang宏的用法的时候,记住一个要点:rust lang的宏思想基于匹配(match),实际上这门语言的基本思想都是基于匹配.
rust lang的宏规则写法是:
macro_rules! macro_name {
() =>{{
...
}}
}
上面的基本规则怎么理解呢,我们知道rust调用宏的语法是 macro_name!() ,那么这里”()”代表上面宏规则的”()”,”{}”代表宏块.
先看一个简单的例子:
macro_rules! MyMacro{
($x:expr)=>{{
$x
}}
}
上面怎么理解呢:”$”读作匹配 , “$x:expr”可读作匹配x,并且x是一个表达式,”$x”后的”:”表示”$x”的属性,rust的宏匹配有很多属性,这里可以看官方手册,”{$x}”表示返回匹配的x的值(注意这里的$x没有分号),
然后我们可以这样使用:
let z=MyMacro!(10000); //z的值将会是10000
看这个官方的例子:
let x: Vec<u32> = vec![1, 2, 3];
宏展开之后应该是这样子的:
let x: Vec = {
let mut temp_vec = Vec::new();
temp_vec.push(1);
temp_vec.push(2);
temp_vec.push(3);
temp_vec
};
那么实现的代码如下:
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}
上面的代码怎么理解呢:我们知道正则表达式的”*”表示匹配0个或者多个,”+”表示匹配一个或者多个,”?”表示匹配0个或者一个,上面的
“*”就代表匹配0个或者多个的”$x:expr”,$(temp_vec.push($x))*表示匹配0个或者多个push方法,然后这个宏返回Vec对象。
我们再来看另外一个不同的例子:
macro_rules! MyMacro{
(x=>$v:expr) => ($v)
}
这个例子可能有些人会疑惑,右边不是”{ }”吗,为何变成”( )”了,这里说明一下,rust lang宏块可以是”[ ]”,”{ }”和”()”,具体看官方手册,
我这里不详细说明,这个文章重点在于列出难理解的部分。其实右边的”( )”换成
“{ }”也可以.
上面的宏使用例子如下
let z=MyMacro!(x=>1000);
/*注意这里不能写成 y=>1000,因为之前讲过,rust的宏思想是基于匹配*/
/* 上面的宏如果是这样 */
macro_rules! MyMacro2{
(1,x=>$v:expr) => ($v)
}
// 调用时如下
let zz=MyMacro2!(1,x=>1000);
读到这里,你或许知道rust macro的用法了吧😊,更多详细说明请观看官方的教程,
链接如下:
https://doc.rust-lang.org/1.7.0/book/macros.html