J'ai deux modules dans des fichiers séparés dans la même caisse, où la caisse a macro_rules
activée. Je veux utiliser les macros définies dans un module dans un autre module.
// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)
// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?
Je frappe actuellement l'erreur du compilateur "macro undefined: 'my_macro'
"... ce qui est logique; le système de macros s'exécute avant le système de modules. Comment contourner cela?
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
bar!(); // works
Si vous souhaitez utiliser la macro dans la même caisse, le module dans lequel votre macro est définie a besoin de l'attribut #[macro_use]
.
Les macros ne peuvent être utilisées qu'après qu'elles ont été définies. Cela signifie que cela ne fonctionne pas:
bar!(); // ERROR: cannot find macro `bar!` in this scope
#[macro_use]
mod foo {
macro_rules! bar {
() => ()
}
}
Pour utiliser votre macro macro_rules!
À partir d'autres caisses, la macro elle-même a besoin de l'attribut #[macro_export]
. La caisse d'importation peut alors importer la macro via use crate_name::macro_name;
.
// --- Crate `util` ---
#[macro_export]
macro_rules! foo {
() => ()
}
// --- Crate `user` ---
use util::foo;
foo!();
Remarque : les macros vivent toujours au niveau supérieur d'une caisse; donc même si foo
serait à l'intérieur d'un mod bar {}
, la caisse user
devrait quand même écrire use util::foo;
et pasuse util::bar::foo;
.
(Avant Rust 2018, vous deviez importer une macro à partir d'autres caisses en ajoutant l'attribut #[macro_use]
À l'instruction extern crate util;
. Cela importerait toutes les macros de util
. Alternativement, #[macro_use(cat, dog)]
pourrait être utilisé pour importer uniquement les macros cat
et dog
. Cette syntaxe ne devrait plus être nécessaire.)
Plus d'informations sont disponibles dans The Rust Programming Language .
Cette réponse est obsolète depuis Rust 1.1.0-stable.
Vous devez ajouter #![macro_escape]
Au sommet de macros.rs
et l'inclure à l'aide de mod macros;
comme mentionné dans le Guide des macros .
$ cat macros.rs
#![macro_escape]
#[macro_export]
macro_rules! my_macro {
() => { println!("hi"); }
}
$ cat something.rs
#![feature(macro_rules)]
mod macros;
fn main() {
my_macro!();
}
$ rustc something.rs
$ ./something
hi
Pour référence future,
$ rustc -v
rustc 0.13.0-dev (2790505c1 2014-11-03 14:17:26 +0000)
Ajouter #![macro_use]
en haut de votre fichier contenant des macros provoquera l'extraction de toutes les macros dans main.rs.
Par exemple, supposons que ce fichier s'appelle node.rs:
#![macro_use]
macro_rules! test {
() => { println!("Nuts"); }
}
macro_rules! best {
() => { println!("Run"); }
}
pub fn fun_times() {
println!("Is it really?");
}
Votre main.rs ressemblerait parfois à ceci:
mod node; //We're using node.rs
mod toad; //Also using toad.rs
fn main() {
test!();
best!();
toad::a_thing();
}
Enfin, disons que vous avez un fichier appelé toad.rs qui nécessite également ces macros:
use node; //Notice this is 'use' not 'mod'
pub fn a_thing() {
test!();
node::fun_times();
}
Notez qu'une fois les fichiers extraits dans main.rs avec mod
, les autres fichiers y ont accès via le mot clé use
.