我们从熟悉的 println! 开始, 了解下声明宏的大致结构吧
同系列传送门:
大家应该都用过一个宏:
当你刚刚接触它的时候, 可能会感到些许疑惑, 为什么后面要跟个感叹号? 为什么括号里面的参数可以不一样?
亲爱的 TRPl 在教你写 Hello World! 时告诉过你: 名字后加个感叹号,就是个宏(macro)
可 macro 到底是啥? (算了算了,反正只要会用就行了,于是你点击了该网页的叉叉)
我们可以利用各自的编辑器查看其定义:
// 你可能会看到, 在 println! 的上面
// 有着类似下面的玩意:
//
// #[macro_export]
// #[stable(feature = "rust1", since = "1.0.0")]
// #[allow_internal_unstable(print_internals, format_args_nl)]
//
// 这些也属于宏, 不过是 `过程宏`
// 而该系列要讲的是 `声明宏`, 因此略过
你悲催地发现, 根本看不懂这堆鬼画符... 但没事, 到后面几节你肯定就懂, 现在只需明白的是大致结构:
macro_rules!
放在println
前面,说明后者是个宏 (macro_rules!
当作特定语法即可)问题来了, 那对花括号内, 也就是具体定义里, 到底干着怎么的事?
请容许我来帮你粗暴地类比一下match表达式 && macro
:
// match
match num
// macro
macro有点像是match,能根据不同参数,展开不同的代码, 在macro最外层的花括号中,有许多匹配分支, 想match一样:
match:
arm
macro:
rule
(明白为什么使用macro_rules!
创建宏了吗)你并不需搞清所有细节,现在先不用试图记忆具体语法,有印象即可
现在再来看看 println
,是不是稍微有点感觉了(看不懂的地方依然直接跳即可):
// 定义部分
// 使用部分
let s = "xxx";
println!;
println!;
xxx
的宏, 用 {}
包裹住具体定义的内容
本节只是为了留个大致印象, 建立一个整体结构的认知, 相信你肯定还有一些疑惑, 后面会比较系统地讲解
咱们下期见
上一篇: p1~> 系列说明
下一篇: p3~> 声明与使用