[module] 모듈 파일에서 매크로를 어떻게 사용합니까?

상자가 macro_rules활성화 된 동일한 상자 내에 별도의 파일에 두 개의 모듈이 있습니다. 다른 모듈의 한 모듈에 정의 된 매크로를 사용하고 싶습니다.

// 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?

나는 현재 컴파일러 오류 ” macro undefined: 'my_macro'“를 쳤다 . 매크로 시스템은 모듈 시스템보다 먼저 실행됩니다. 이 문제를 어떻게 해결합니까?



답변

동일한 상자 내의 매크로

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

bar!();    // works

동일한 크레이트에서 매크로를 사용하려면 매크로가 정의 된 모듈에 속성이 필요합니다 #[macro_use].

매크로는 정의 된 후에 만 사용할 수 있습니다 . 이것은 이것이 작동하지 않음을 의미합니다.

bar!();  // ERROR: cannot find macro `bar!` in this scope

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

상자를 가로 지르는 매크로

macro_rules!다른 상자 의 매크로 를 사용하려면 매크로 자체에 속성이 필요합니다 #[macro_export]. 가져 오는 상자는를 통해 매크로를 가져올 수 있습니다 use crate_name::macro_name;.

나무 상자 util

#[macro_export]
macro_rules! foo {
    () => ()
}

나무 상자 user

use util::foo;

foo!();

매크로는 항상 상자의 최상위 수준에 있습니다. 해도 너무 foo돌며 것 mod bar {}user상자는 여전히 작성해야 use util::foo;하고 하지 use util::bar::foo; .

Rust 2018 이전 #[macro_use]에는 extern crate util;명령문에 속성 을 추가하여 다른 상자에서 매크로를 가져와야했습니다 . 모든 매크로를 util. 또는 #[macro_use(cat, dog)]매크로 catdog. 이 구문은 더 이상 필요하지 않습니다.

더 많은 정보는 The Rust Programming Language 장에서 매크로에 관한 것 입니다.


답변

이 답변은 Rust 1.1.0-stable에서 구식입니다.


매크로 가이드에 언급 된대로 #![macro_escape]맨 위에 추가 macros.rs하고 포함해야합니다 .mod 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

향후 참조를 위해

$ rustc -v
rustc 0.13.0-dev (2790505c1 2014-11-03 14:17:26 +0000)


답변

#![macro_use]매크로가 포함 된 파일의 맨 위에 추가 하면 모든 매크로가 main.rs로 풀링됩니다.

예를 들어이 파일이 node.rs라고 가정 해 보겠습니다.

#![macro_use]

macro_rules! test {
    () => { println!("Nuts"); }
}

macro_rules! best {
    () => { println!("Run"); }
}

pub fn fun_times() {
    println!("Is it really?");
}

main.rs는 언젠가 다음과 같이 보일 것입니다.

mod node;  //We're using node.rs
mod toad;  //Also using toad.rs

fn main() {
    test!();
    best!();
    toad::a_thing();
}

마지막으로 다음 매크로가 필요한 toad.rs라는 파일이 있다고 가정 해 보겠습니다.

use node; //Notice this is 'use' not 'mod'

pub fn a_thing() {
  test!();

  node::fun_times();
}

mod를 사용하여 파일 을 main.rs로 가져 오면 나머지 파일은 use키워드를 통해 파일에 액세스 할 수 있습니다 .


답변

나는 Rust 1.44.1에서 같은 문제 를 발견했고,이 솔루션은 이후 버전에서 작동합니다 (Rust 1.7에서 작동하는 것으로 알려짐).

다음과 같은 새 프로젝트가 있다고 가정합니다.

src/
    main.rs
    memory.rs
    chunk.rs

에서 main.rs , 그렇지 않으면, 당신을 위해하지 않을 것이다, 당신은 소스에서 매크로를 가져 오는 것을 주석이 필요합니다.

#[macro_use]
mod memory;
mod chunk;

fn main() {
    println!("Hello, world!");
}

따라서 memory.rs 에서 매크로를 정의 할 수 있으며 주석이 필요하지 않습니다.

macro_rules! grow_capacity {
    ( $x:expr ) => {
        {
            if $x < 8 { 8 } else { $x * 2 }
        }
    };
}

마지막으로 chunk.rs 에서 사용할 수 있으며 main.rs 에서 수행되기 때문에 여기에 매크로를 포함 할 필요가 없습니다.

grow_capacity!(8);

upvoted 답변 으로, 저를 위해 혼란을 야기 예에 의해이 doc , 너무 도움이 될 것입니다.


답변