Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

展开与求值语义

宏调用在模型上是什么

调用 m!(a, b) 时,编译器将 ab语法片段代入宏体中 $ 占位符的位置,得到一段新的 Move 代码,再继续类型检查。

这与普通函数 f(a, b) 不同:普通函数会先对 ab 求值(遵守 Move 的所有权与借用规则),再把传入。

表达式代入(直观例子)

若宏定义为:

macro fun twice($e: u64): u64 { $e + $e }

twice!(x + 1) 展开后近似于 (x + 1) + (x + 1)(具体以编译器展开为准)。若 x + 1 有副作用或消耗性操作,语义上会与「先算一次再乘二」不同——因此宏适合纯表达式场景,或配合 lambda 明确控制求值次数。

与「先求值再调用」的对比

特性普通 funmacro fun
实参先求值为值片段代入宏体
是否适合传递「未执行的代码块」需额外结构包装可用 lambda 参数(见下一节)

小结

把宏理解为在类型检查之前完成的、带类型的语法变换,有助于你阅读标准库宏展开后的行为。下一节介绍 lambda 形参——只有宏才能声明的那种。