macro_rules! 는 패턴을 매칭해. 절차적 매크로는 더 나아가: 토큰 스트림을 받아 토큰 스트림을 반환하는 Rust 함수야 — 코드를 변형하는 임의 코드. 제일 중요한 종류가 네가 계속 쓴 거야: derive.
세 종류
Derive 매크로 — #[derive(Debug, Clone)] — struct 나 enum 정의에서 trait impl 을 생성. Attribute 매크로 — #[tokio::main], #[test] — 표기한 항목을 변형. Function-like 매크로 — sql!(...) — macro_rules! 호출처럼 보이지만 임의 Rust 를 돌려 확장을 만들어.
쓰는 것보다 훨씬 많이 소비해
절차적 매크로 작성은 고급이야 — 자기 크레이트에 살고, syn 크레이트로 토큰을 파싱하고, quote 로 코드를 생성해. 대부분 러스타시안은 안 써. 근데 계속 써: 모든 #[derive(...)], 모든 #[tokio::main], 모든 #[derive(Serialize)] 가 너 대신 컴파일 타임 코드 생성을 하는 절차적 매크로야.
derive 는 매일 쓰는 절차적 매크로야.
#[derive(Debug, Clone, PartialEq)] 는 내장 문법이 아니야 — 네 struct 를 읽어 trait impl 을 써주는 절차적 매크로야. 그걸 이해하면 attribute-and-derive 생태계 전체의 안개가 걷혀: 다 annotation 으로 촉발되는 코드 생성이야.비용-편익
절차적 매크로는 거대한 보일러플레이트를 없앨 수 있어 — serde 가 50필드 struct 의 직렬화를 한 줄에서 derive 해. 비용은 컴파일 타임 (미니 컴파일러를 돎) 이랑 불투명성 (생성된 코드가 안 보임). 잘 테스트된 생태계 매크로엔 그 거래가 거의 항상 값해; 직접 쓰기 전엔 더 고민해.