[Rust] 매크로에 대해 알아보자

devlcw·2024년 3월 7일

Rust Macro

목록 보기
1/1

이번에는 러스트 매크로에 대해 알아보겠다. 기본적으로 러스트는 다른 언어들과 다르게 매크로도 컴파일 된다. 잘 알려진 C언어의 매크로는 다음과 같다.

#define MAIN(argc, argv) main(int argc, char *argv[])

int MAIN(argc, argv) {
    return 0;
}

이런식으로 단순 치환이 된다.
하지만 러스트는 이런 단순 치환에 목적을 둔 매크로라기 보단 언어 자체가 장황해서 단축시켜 사용할 목적으로 만들어진 매크로이기 때문에 따로 문법을 익혀야 한다.

다음은 expr에서 From trait이 구현된 새로운 String을 생성하는 매크로이다.

macro_rules! S {
    ($e:expr) => {
        String::from($e)
    }
}

let foo = S!("hello");

메타변수

다른 언어의 매크로들과는 다르게 메타변수라는게 있다.
$e:expr 부분이 메타변수이다.

expr 타입을 가진 어떤 러스트 문법도 저 변수에 들어갈 수 있다는 얘기이다.

macro_rules! twice {
	($e:expr) => {
    	{
        	$expr;
        	$expr;
        }
    }
}

twice!(println!("hello world!"));

// output
// hello world
// hello world

물론 expr 이외에 여러가지 메타변수들이 있다.

아래는 메타변수들 matcher의 종류이다

  • expr: 모든 표현식
  • ident: 식별자
  • path: 경로 표현식. 예를 들어, std::collections::HashMap 같은 모듈, 크레이트, 아이템의 경로
  • ty: 타입. 예를 들어, i32, f64, Vec<T>, &str 등의 타입들
  • block: 중괄호 {}로 둘러싸인 코드 블록. 블록 내에는 여러 문장과 표현식이 포함될 수 있음
  • stmt: 문장. 선언문, 표현문 등이 해당됨
  • pat: 패턴. match 문이나 if let 구문에서 사용되는 패턴 매칭
  • item: 아이템을 매칭합니다. fn, struct, enum, 상수 등 최상위 구성 요소
  • meta: 속성 내용. 예를 들어, #[derive(Debug)]에서 derive(Debug) 부분이 해당됨
  • tt: 토큰 트리. 거의 모든 종류의 구문을 포함할 수 있는 가장 유연한 매처임

이런 메타변수들을 가지고 라이브러리를 만들 때 확장성 있는 매크로와 함께 나만의 라이브러리를 만들 수 있을 것이다.

한 포스트에서는 패턴 매쳐들을 다루기 힘드니 여러 포스트로 나눠서 소개하고 써보도록 하겠다.

profile
모든 스택에는 이유가 있다

0개의 댓글