rust macro

wangki·2025년 3월 10일
0

Rust

목록 보기
27/54

개요

binance api 통신을 하면서 query를 만들기위해서 매크로를 활용하다가 정리하고 싶어서 글을 작성하게 되었다.

내용

rust macro

macro_use vs marcro_export
둘 다 매크로를 정의하는데 사용되는 속성(attributes)이지만, 서로 다른 역할을 수행한다.

macro_export

  • 정의된 매크로를 다른 모듈이나 크레이트에서 사용할 수 있도록 공개하는 역할을 합니다.
  • macro_export가 선언된 매크로는 항상 pub으로 간주하며, 다른 크레이트에서도 해당 매크로를 사용할 수 있다.
  • macro_export로 선언된 매크로는 크레이트 루트 스코프에서 사용할 수 있다.

macro_use

  • 외부 크레이트 또는 모듈에서 정의된 매크로를 현재 스코프에서 사용할 수 있도록 가져오는 역할을 합니다.
  • expr(expression)
    • rust에서 값을 생성하는 코드 조각을 의미
    • 변수, 리터럴, 연산자, 함수 호출 등을 포함하는 모든 유효한 러스트 표현식이 expr에 해당한다.
    • 매크로 내에서 expr타입 매개변수는 런타임에 평가되어 값을 생성한다. -> 런타임에 코드가 실행된다는 의미인거임
  • ident(identifier)
    • 변수, 함수, 구조체, 트레잇 등 러스트 코드에서 이름을 붙이는 데 사용되는 식별자를 의미합니다.
    • 매크로 내에서 ident 타입 매개변수는 런타임에 평가되지 않고, 코드 생성에 사용됩니다.
  • ty(type)
    • 러스트에서 변수, 함수 매개변수, 반환 값 등의 데이터 타입을 나타냅니다.
    • 기본 타입, 사용자 정의 타입, 제네릭 타입 등 모든 유효한 러스트 타입이 ty에 해당합니다.
    • 매크로 내에서 ty 타입 매개변수는 런타임에 평가되지 않고, 코드 생성에 사용됩니다.

반복 매개변수 패턴

$(...) 안에 정의하고, 뒤에 반복 연산자(*, +, ?)를 사용하여 반복적으로 매개변수를 받을 수 있다.

  • *: 0번 이상 반복
  • +: 1번 이상 반복
  • ?: 0번 또는 1번 반복
marcro_rules! my_macro {
    ($($x:expr),*) => {
        // ....
    };
}

0개 이상의 표현식을 매개변수로 받는다는 의미이다.

예시

#[macro_export]
macro_rules! query_build {
    ($($field:expr),*) => {
        {
            let mut query = String::new();
            $(
                if !query.is_empty() {
                    query.push('&');
                }
                query.push_str(&format!("{}={}", stringify!($field), $field));
            )*
            query
        }
    };
}

결론

매크로는 일반 함수에서 구현할 수 없는 강력한 무기인 것 같다. 그러나 지나치게 사용하게 되면 오히려 가독성과 디버깅에서 안 좋을 수 있다는 생각이 든다.
특히 함수적으로 사용을 지향해야 할 것 같다.

0개의 댓글