Если я пишу
#[macro_use]
mod macros {
pub fn global () -> i32 {100}
macro_rules! test {
($x:expr, $y:expr) => {
{let local = $x;
global() + $y + local}}
}
}
fn main() {
let local = 10;
fn global () -> i32 {1000}
let x = 10000;
println!("{}", x + test!(1,local));
}
, я получаю 11011. Это указывает на то, что ссылка на local
в вызове макроса (которая была равна 10) не была захвачена вхождением let local = ...
в определение макроса. Это правильное поведение гигиены c.
OTOH, если я напишу
#[macro_use]
mod macros {
pub fn global () -> i32 {100}
macro_rules! test {
($x:expr, $y:expr) => {
{fn local () -> i32 {$x}
(global() + $y + local())}}
}
}
fn main() {
fn local () -> i32 {100000} // a big number
fn global () -> i32 {1000}
let x = 10000;
println!("{}", x + test!(3,local()));
}
Это печатает 11006
, указывая, что $y
, который должен был быть связан с процедурой local
на сайте вызова макроса (возвращающий 100000) был захвачен значением local
на сайте определения (возвращая 3).
Может кто-нибудь объяснить это? Это ошибка компилятора или есть разница между let
-связью и fn
-связью, которую я не понимаю?