2017-10-09 18 views
1

我有一个变得太大的宏,所以我想将部分代码提取到函数中。当我这样做,我有一个问题,因为当宏是在调用点扩展的功能在范围:如何在宏中使用非公共函数?

#[macro_use] 
mod macros { 
    fn hi() { 
     println!("Hello") 
    } 

    #[macro_export] 
    macro_rules! say_hi { 
     () => { 
      hi(); 
     }; 
    } 
} 

fn main() { 
    say_hi!(); 
} 

这并不编译:

error[E0425]: cannot find function `hi` in this scope 
    --> src/main.rs:10:13 
    | 
10 |    hi(); 
    |    ^^ not found in this scope 
... 
16 |  say_hi!(); 
    |  ---------- in this macro invocation 
    | 
help: possible candidate is found in another module, you can import it into scope 
    | 
15 | fn main() use macros::hi; 
    | 

我试图使hi公共(虽然我不想),但由于它不是在调用者的上下文中导入的,所以它不起作用。

我该如何解决这个问题?

回答

1

第一个问题是,在宏的调用者的上下文中,除非该函数是公共的,否则该函数不可见,因此我恐怕无法从宏调用非pub函数。

另一个问题是,宏引用的函数应该始终使用它们的完全限定路径(以便它们可以从任何上下文运行)。假设功能hipub,这将工作:

#[macro_export] 
macro_rules! say_hi { 
    () => { 
     $crate::macros::hi(); 
    }; 
} 

注:使用$crate任何板条箱使用时,确保宏观作品,看到$crate documentation了解详情。

+2

一个共同点是一些指标,它不是公共前缀的函数名(例如'__private_hi()'),然后标记功能'#[DOC(隐藏)]'所以它不容易出现。在宏中使用特殊的'$ crate'变量也是很好的做法。 – Shepmaster

+0

我不认为$箱子的作品... – Renato

+1

[我不知道你为什么这么说](https://doc.rust-lang.org/book/first-edition/macros.html#the-可变板条箱)。 – Shepmaster

相关问题