Почему привязки разрешены гигиенически c, а привязки - нет? - PullRequest
0 голосов
/ 25 февраля 2020

Если я пишу

#[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 -связью, которую я не понимаю?

...