Rust 宏无法在范围内找到值

v22*_*v22 3 macros rust

我制作了一个 Rust 宏,它实际上将一些代码粘贴到我调用它的地方。我将一些东西硬编码到那里,不幸的是它找不到。

这就是我的代码的结构:

macro_rules! foo {
    println!("{}", number);
}

fn bar() {
    let number: i32 = 10;
    foo!(); //--> cannot find 'number', even if it is right above here
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*all 5

这是因为宏观卫生。宏内部引入的本地标识符不能在外部使用,反之亦然。

这种设计选择的原因是宏不会意外地更改不相关代码的行为。您无需研究宏的实现即可确定它不会与您自己的代码发生命名冲突。

这有点像函数内部的局部变量对调用函数不可见。更改函数中局部变量的名称不会破坏或更改调用该函数的代码的含义。

有两种主要方法可以实现您想要的功能:

  1. 将标识符作为参数传递给宏。这样,标识符标记源自宏外部,因此允许引用该范围内的标识符:
    macro_rules! foo {
        ($ident: ident) => {
             println!("{}", $ident);
        }
    }
    
    fn bar() {
        let number: i32 = 10;
        foo!(number);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 另一种方法是定义宏,以便变量已经在宏定义要使用的范围内。参见 用户2722968的回答。此解决方案的缺点是您对在何处调用它非常有限。