2015-03-16 10 views
11

Jestem pewien, że to jest trywialne, ale nie mogę sprawić, żeby działało.Jak używasz makra z jego własnej skrzynki?

Szukałem na http://doc.rust-lang.org/book/advanced-macros.html#scoping-and-macro-import/export i doceniam, że ogólnie rzecz biorąc, sposób używania makr jest definiować je za pomocą:

#[macro_export] 
macro_rules! background(($token:expr) => (($token >> (32 + 8)) & $crate::graphics::mask::Color)); 

... a następnie importować je do innego kontekstu, który z nich korzysta używając:

#[macro_use] 
extern crate terminal; 
... 

Jednak ja chcę użyć makr z poziomu skrzynki, w której są zdefiniowane.

Jeśli moja struktura plików jest:

- lib.rs 
- macros.rs 
- foo 
- foo/mod.rs 
- foo/junk.rs 

Jak korzystać z makr w macros.rs z junk.rs?

Próbowałem różnych kombinacji #[macro_use] mod macros itp. Bez powodzenia. Dokumentacja sugeruje, że jeśli makro jest zdefiniowane w pewnym zakresie, to jest dostępne we wszystkich modułach potomnych ... Czy to znaczy, że muszę zdefiniować moje makra w lib.rs?

Odpowiedz

11

Trzeba zaznaczyć swoją makro z #[macro_export] a następnie zaznaczyć moduł z #[macro_use]:

#[macro_use] 
mod macros { 
    #[macro_export] 
    macro_rules! my_macro(() => (42)); 
} 

pub mod foo { 
    pub mod junk { 
     pub fn usage() -> u8 { 
      my_macro!() 
     } 
    } 
} 

fn main() { 
    println!("{:?}", foo::junk::usage()); 
} 

Technicznie rzecz biorąc, trzeba tylko użyć #[macro_export] jeśli chcesz makro mają być dostępne dla użytkowników swojej skrzyni.

(Playpen link)

+0

inline, który działa, ale gdy próbuję go przy użyciu plików, to nie wydaje się; spójrz na ten banalny przykład https://github.com/shadowmint/rust-starter; to błąd z "src/module1/blah.rs: 2: 15: 2:18 błąd: makro niezdefiniowane:" fmt! "", ale https://raw.githubusercontent.com/shadowmint/rust-starter/master/src /lib.rs robi dokładnie to, co powiedziałeś. – Doug

+0

Nie ma "mod module1;" w kodzie, który łączysz, może błąd pochodzi z czegoś innego? – huon

+0

(Zobacz także: http://doc.rust-lang.org/nightly/book/advanced-macros.html#scoping-and-macro-import/export.) – huon

37

Zaakceptowanych odpowiedź jest poprawna, ale dla każdego, kto znajdzie na to pytanie w przyszłości, chciałbym dodać, że zamówienie w której moduły są ładowane jest ważne.

Na przykład, w tej kolejności:

pub mod terminal; 
pub mod terminals; 
pub mod graphics; 

#[macro_use] 
mod macros; 

Jeżeli terminal używa makro z makra, będzie nie pracy; #[macro_use] musi nastąpić powyżej każdy inny moduł, który używa makra:

#[macro_use] 
mod macros; 

pub mod terminal; 
pub mod terminals; 
pub mod graphics; 
+0

To był dokładnie mój problem! Chciałbym, żeby zostało to podkreślone w książce. – SummerBreeze

Powiązane problemy