[Rust 공식문서 한국어 정리] 68. Rust 속성 매크로(Attribute Macros) 가이드
[Rust 공식문서 한국어 정리] 68. Rust 속성 매크로(Attribute Macros) 가이드
원문 제목: Attribute Macros — The Rust Reference
작성자: Rust Language Team
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📌 1. 서론 — 이 문서가 다루는 내용
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
이 문서는 #[attribute_name] 형태로 선언된 항목을 다른 코드로 변환하는 속성 매크로(Attribute Macro)를 설명합니다.
derive 매크로와 달리, 속성 매크로는 임의의 항목(함수, 구조체, 모듈 등)을 변환할 수 있습니다.
proc_macro_attribute 속성으로 정의하고, 입력 항목의 TokenStream을 변환하여 출력하는 방법을 다룹니다.
라우팅, 인증, 계측(instrumentation), API 문서화 등 다양한 실전 적용 사례를 중심으로 설명합니다.
프레임워크 개발자와 도메인 특화 언어(DSL) 설계자에게 필수적인 고급 메타프로그래밍 기법입니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔑 2. 핵심 개념 4가지
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
① proc_macro_attribute: 속성 매크로를 정의하는 매크로 속성입니다.
② TokenStream 변환: 입력 항목을 파싱하고, 변환된 코드를 새 TokenStream으로 반환합니다.
③ Item Decoration: 함수나 구조체에 메타데이터를 추가하거나, 래퍼 코드를 자동 생성합니다.
④ Compile-time Code Generation: 컴파일 타임에 코드를 변환하여 보일러플레이트를 제거합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📖 3. 주요 내용 상세
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
속성 매크로는 #[proc_macro_attribute]로 정의합니다.
pub fn my_attr(attr: TokenStream, item: TokenStream) -> TokenStream { ... } 형태의 함수입니다.
attr은 속성 자신의 인자, item은 속성이 붙은 대상 항목의 TokenStream입니다.
두 개의 TokenStream을 모두 처리할 수 있으므로, 매우 유연한 변환이 가능합니다.
#[route("/users")] fn handler() { ... }에서 attr은 "/users", item은 함수 정의입니다.
매크로는 함수 정의를 분석하여, 라우팅 테이블 등록 코드와 원본 함수를 함께 생성할 수 있습니다.
actix-web의 #[get("/")], tokio::main, tracing::instrument 등이 모두 속성 매크로입니다.
#[tokio::main]은 fn main()을 tokio::runtime::Runtime::new().block_on(async { ... })로 감쌉니다.
#[tracing::instrument]는 함수의 진입과 퇴장을 span으로 감싸고, 인자를 자동으로 기록합니다.
속성 매크로는 derive보다 강력하지만, 오용 위험도 큽니다.
입력 항목의 구조를 완전히 바꿀 수 있으므로, 예상치 못한 부작용이 발생할 수 있습니다.
매크로 작성 시 Span 정보를 보존하여, 생성된 코드의 컴파일 에러가 원본 코드 위치를 가리키도록 해야 합니다.
테스트와 디버깅은 proc-macro2를 활용합니다.
TokenStream을 문자열로 출력하거나, prettyplease로 포맷팅하여 생성된 코드를 검토합니다.
속성 매크로의 동작을 이해하려면 cargo expand로 확장된 코드를 직접 확인하는 것이 가장 효과적입니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🛠 4. 실전 활용
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
웹 프레임워크에서 #[get("/")], #[post("/")]로 라우팅 정보를 함수에 선언적으로 부여합니다.
#[instrument]로 모든 함수 호출에 자동으로 tracing span을 추가하여 관찰 가능성을 확보합니다.
#[tokio::main]과 #[tokio::test]로 비동기 진입점을 자동으로 설정합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 5. 정리
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
속성 매크로는 Rust의 가장 강력한 메타프로그래밍 도구 중 하나입니다.
함수, 구조체, 모듈을 변환하여 보일러플레이트를 제거하고, 선언적 DSL을 구축합니다.
강력함만큼 책임도 크므로, Span 보존과 예측 가능한 동작을 항상 우선하세요.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔗 출처 링크
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
원문: https://doc.rust-lang.org/reference/procedural-macros.html
cargo-expand: https://github.com/dtolnay/cargo-expand
#Rust #AttributeMacro #ProcMacro #MetaProgramming #DSL #Framework #번역

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