[Rust 공식문서 한국어 정리] ㉜. Rust 프로시저 매크로(Procedural Macros) 가이드
[Rust 공식문서 한국어 정리] ㉜. Rust 프로시저 매크로(Procedural Macros) 가이드
원문 제목: Procedural Macros — The Rust Reference
작성자: Rust Language Team
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📌 1. 서론 — 이 문서가 다루는 내용
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
이 문서는 Rust의 프로시저 매크로(Procedural Macro)를 작성하는 방법을 체계적으로 설명합니다.
선언적 매크로(macro_rules!)를 넘어, 컴파일 타임에 Rust 코드를 생성하는 강력한 도구인 proc macro를 다룹니다.
Derive, Attribute, Function-like 세 가지 종류의 프로시저 매크로와 그 작성 방법, 제약, 모범 사례를 설명합니다.
TokenStream을 다루고, syn/quote 크레이트를 활용해 복잡한 AST 파싱을 단순화하는 기법도 포함합니다.
메타프로그래밍과 도메인 특화 언어(DSL)에 관심 있는 Rust 개발자에게 고급 주제입니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔑 2. 핵심 개념 4가지
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
① Derive Macro: #[derive(TraitName)] 형태로 구조체/열거형에 자동으로 트레이트 구현을 생성합니다.
② Attribute Macro: #[attribute_name] 형태로 선언된 항목을 다른 코드로 변환합니다.
③ Function-like Macro: macro_name!(...) 형태로 호출되며, 임의의 토큰을 입력받아 코드를 생성합니다.
④ TokenStream: proc_macro의 기본 입출력 단위로, Rust 소스 코드를 토큰 단위로 표현합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📖 3. 주요 내용 상세
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
프로시저 매크로는 proc-macro 타입의 크레이트로 작성됩니다.
Cargo.toml에서 [lib] crate-type = ["proc-macro"]를 지정해야 하며, proc-macro 크레이트에 의존합니다.
proc_macro::TokenStream을 입력으로 받고, 변환된 TokenStream을 반환하는 함수를 정의합니다.
Derive 매크로는 #[proc_macro_derive(TraitName)]으로 선언합니다.
입력으로는 구조첵나 열거형의 TokenStream이 들어오며, 출력으로는 impl 블록을 생성합니다.
syn 크레이트는 TokenStream을 파싱해 DeriveInput 구조체로 변환하여, 필드와 제네릭 정보를 쉽게 접근할 수 있게 합니다.
quote! 매크로는 템플릿 기반으로 TokenStream을 생성하여, 복잡한 코드 조립을 간결하게 만듭니다.
Attribute 매크로는 #[proc_macro_attribute]로 선언합니다.
두 개의 TokenStream을 받습니다: 하나는 속성 자신의 인자, 다른 하나는 속성이 붙은 항목입니다.
이를 통해 함수나 모듈 전체를 래핑하거나, 계측(instrumentation), 라우팅 등의 메타데이터를 주입할 수 있습니다.
Function-like 매크로는 #[proc_macro]로 선언합니다.
macro_rules!와 유사하게 보이지만, 훨씬 유연하게 임의의 문법을 파싱할 수 있습니다.
SQL 쿼리, 정규식, HTML 템플릿 등을 컴파일 타임에 검증하고 변환하는 DSL로 자주 사용됩니다.
매크로 작성 시 주의할 점은 Hygiene(위생)과 Span 정보입니다.
proc_macro는 기본적으로 위생을 보장하며, 생성된 변수가 호출자의 네임스페이스를 오염시키지 않습니다.
Span은 생성된 코드의 오류 메시지 위치를 정확히 매핑하는 데 사용되며, 사용자 경험에 큰 영향을 줍니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🛠 4. 실전 활용
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
serde의 Serialize/Serialize, tokio의 #[main], actix-web의 #[get("/")] 등이 모두 프로시저 매크로입니다.
자체 ORM이나 설정 파일 파서를 proc macro로 작성하여 컴파일 타임 검증을 강화합니다.
syn/quote를 활용해 AST 파싱과 코드 생성의 보일러플레이트를 줄이고, Span을 정확히 전달해 디버깅을 용이하게 합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 5. 정리
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
프로시저 매크로는 Rust 메타프로그래밍의 정점입니다.
Derive, Attribute, Function-like 세 종류를 적재적소에 활용하면 반복적인 코드를 극적으로 줄일 수 있습니다.
TokenStream과 syn/quote를 익히면 거의 모든 컴파일 타임 코드 생성이 가능해집니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔗 출처 링크
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
원문: https://doc.rust-lang.org/reference/procedural-macros.html
The Little Book of Rust Macros: https://danielkeep.github.io/tlborm/book/index.html
#Rust #ProcMacro #Macro #Derive #MetaProgramming #DSL #번역

오뉴노노 님의 최근 댓글
ㅋㅋㅋㅋㅋ 2019 01.14 잘 읽었습니다 2018 12.30 포인트가 없어서 아직 시작을 못하고있는데요! 글은 잘 읽었습니다! 포인트 쌓고 도전할거에요 2018 12.30