C.W.K.
Stream
Lesson 03 of 04 · published

절차적 매크로 & derive

~11 min · macros, procedural, derive

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

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 해. 비용은 컴파일 타임 (미니 컴파일러를 돎) 이랑 불투명성 (생성된 코드가 안 보임). 잘 테스트된 생태계 매크로엔 그 거래가 거의 항상 값해; 직접 쓰기 전엔 더 고민해.

Code

annotation 하나로 호출하는 절차적 매크로·rust
// 이건 안 써 — USE 해. 각각 절차적 매크로야:

#[derive(Debug, Clone, PartialEq)] // derive 매크로: trait impl 생성
struct Point { x: i32, y: i32 }

// #[tokio::main]    -> attribute 매크로: async main 을 런타임으로 재작성
// #[derive(serde::Serialize)] -> serde 의 derive 매크로: ser/de 생성

fn main() {
    let p = Point { x: 1, y: 2 };
    let q = p.clone();             // Clone — derive 가 생성
    println!("{p:?} == {q:?}: {}", p == q); // Debug + PartialEq, 생성됨
}

External links

Exercise

struct 에 #[derive(Debug, Clone, PartialEq, Default)] 를 더하고 네 동작 ({:?}, .clone(), ==, Type::default()) 을 다 써봐. 각각 derive 매크로가 너 대신 뭘 생성했는지 말해. derive 없이 손으로 썼으면 몇 줄이었을까?
Hint
각 derive 가 풀 trait impl 을 써: Debug 의 포맷터, Clone 의 필드별 복사, PartialEq 의 비교, Default 의 생성자. 손으로면 수십 줄; 네 단어 annotation 이 그걸 다 대체해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.