2017-10-09 44 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

相關問題