0Pricing
Learn Rust Coding · 강의

절차적 매크로: Derive, Function

사용자 정의 `#[derive]` 매크로와 함수형 매크로를 포함한 절차적 매크로를 살펴보고 더 복잡한 코드 생성을 수행합니다.

절차적 매크로: Derive, Function은(는) CoddyKit의 무료 Learn Rust Coding 강의입니다. 이것은 3개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Learn Rust Coding 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.

절차적 매크로 소개

절차적 매크로의 세계에 오신 것을 환영합니다! 선언적 매크로(macro_rules!)와 달리 절차적 매크로는 Rust 코드 자체를 대상으로 동작하는 함수와 비슷합니다.

TokenStream을 input으로 받아 처리한 뒤 또 다른 TokenStream을 반환합니다. 따라서 훨씬 더 복잡한 코드 생성을 수행할 수 있습니다.

절차적 매크로의 유형

Rust는 세 가지 주요 절차적 매크로 유형을 제공합니다.

  • 함수형 매크로: 일반적인 함수 호출처럼 보이고 동작합니다. 예: my_macro!(...)
  • Derive 매크로: #[derive(MyTrait)]를 사용해 구조체와 열거형에 대한 trait을 자동으로 구현할 수 있습니다.
  • 속성 매크로: 항목에 적용할 수 있는 사용자 지정 속성을 정의할 수 있습니다. 예: #[route("/path")]

`proc-macro` 크레이트

절차적 매크로는 자체적인 특수 크레이트 유형에 포함되어야 합니다. Cargo.toml에서 다음과 같이 선언합니다.

이 선언은 해당 크레이트에 컴파일 시 코드를 변환하는 매크로가 포함되어 있음을 Cargo에 알립니다.

[package]
name = "my_macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

함수형 매크로 설명

함수형 매크로는 proc_macro::TokenStream을 받아 하나를 반환하는 함수에 #[proc_macro] 속성을 지정해 정의합니다.

이는 사용자 지정 DSL(도메인 특화 언어)이나 macro_rules!로 처리할 수 없는 복잡한 코드 반복에 유용합니다.

use proc_macro::TokenStream;

#[proc_macro]
pub fn my_function_macro(input: TokenStream) -> TokenStream {
    // Logic to transform input TokenStream
    // ...
    input // For example, return the input unchanged
}

함수형 매크로 예시

개념적인 예시를 살펴보겠습니다. greet_name! 매크로는 출력 문을 생성합니다. 실제 구현에서는 input TokenStream을 parse하여 이름을 추출합니다.

매크로 정의는 복잡하지만, 사용법은 간단하면서도 강력합니다.

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;

#[proc_macro]
pub fn greet_name(input: TokenStream) -> TokenStream {
    // Imagine parsing 'input' to get a name like 'World'
    // and generating: println!("Hello, World!");
    "println!(\"Hello, {}!\", \"CoddyKit\");".parse().unwrap()
}

/* In 'my_app/src/main.rs' */
use my_macros::greet_name;

fn main() {
    greet_name!("CoddyKit");
}

`#[derive]` 매크로 이해하기

Derive 매크로는 가장 일반적인 유형입니다. 구조체나 열거형에 trait을 자동으로 구현할 수 있습니다.

#[derive(Debug)]를 작성하면 컴파일 시 매크로가 실행되어 해당 유형이 Debug trait을 구현하는 데 필요한 코드를 생성합니다.

`#[derive]` 구현하기(개념)

사용자 지정 derive 매크로는 일반적으로 syn(Rust 코드를 AST로 parse하는 데 사용) 및 quote(AST에서 Rust 코드를 생성하는 데 사용)와 같은 라이브러리로 만듭니다.

구조체 또는 열거형을 나타내는 TokenStream을 받아 생성된 trait 구현을 반환하는, #[proc_macro_derive(MyTrait)] 주석이 지정된 함수를 정의합니다.

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
use quote::quote;

#[proc_macro_derive(MyDebug)] // MyDebug is the trait name
pub fn my_debug_derive(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    let name = &ast.ident;

    let expanded = quote! {
        impl std::fmt::Debug for #name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.debug_struct(stringify!(#name)).finish()
            }
        }
    };
    expanded.into()
}

`#[derive(Debug)]` 사용 예시

여러분이 이미 사용해 보았을 가능성이 높은 derive 매크로의 실제 예시를 살펴보겠습니다. Point 구조체에 #[derive(Debug)]를 추가하면 Rust가 Debug trait을 자동으로 구현하므로, 내용을 보기 좋게 출력할 수 있습니다.

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 10, y: 20 };
    println!("My point is: {:?}", p);
}

속성 매크로: `#[my_attribute]`

속성 매크로는 derive 매크로와 비슷하지만 모든 항목(함수, 구조체, 모듈 등)에 적용할 수 있습니다. 속성 매크로는 자신이 적용된 항목과 괄호 안의 모든 인수를 input으로 받습니다.

일반적인 용도로는 웹 프레임워크의 경로 지정(예: #[get("/users")])이나 test 설정(예: #[test])이 있습니다.

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;

#[proc_macro_attribute]
pub fn log_calls(attr: TokenStream, item: TokenStream) -> TokenStream {
    // Imagine adding println! statements to 'item'
    item
}

/* In 'my_app/src/main.rs' */
use my_macros::log_calls;

#[log_calls("entry_point")]
fn my_function() {
    println!("Inside my_function");
}

fn main() {
    my_function();
}

어떤 매크로를 사용할까요

  • 함수형 매크로: 사용자 지정 미니 언어나 임의의 코드 블록에 대한 복잡한 변환에 사용합니다.
  • Derive 매크로: 구조체와 열거형에 trait을 자동으로 구현할 때 사용합니다.
  • 속성 매크로: 사용자 지정 속성을 바탕으로 특정 항목(함수, 구조체) 주변의 코드를 수정하거나 생성할 때 사용합니다.

각 유형은 Rust의 구문과 기능을 확장하는 데 고유한 목적을 가집니다.

빠른 확인: 매크로 유형

다음 중 절차적 매크로에 관한 설명으로 TRUE인 것은 무엇일까요?

복습: 코드 생성의 강력한 기능

절차적 매크로의 고급 세계를 살펴보았습니다!

  • 사용자 지정 구문을 위한 함수형 매크로를 배웠습니다.
  • #[derive] 매크로가 trait 구현을 자동화하는 방식을 이해했습니다.
  • 항목 수준의 코드 생성을 위한 속성 매크로를 간단히 살펴보았습니다.

절차적 매크로는 반복적인 보일러플레이트를 줄이고 Rust의 기능을 확장하는 강력한 도구이며, 코드로 코드를 작성할 수 있게 해 줍니다!

자주 묻는 질문

“절차적 매크로: Derive, Function” 강의는 무료인가요?

네 — “절차적 매크로: Derive, Function” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Learn Rust Coding 강의 전체를 잠금 해제할 수 있습니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.

“절차적 매크로: Derive, Function”에서 뭘 배우나요?

사용자 정의 `#[derive]` 매크로와 함수형 매크로를 포함한 절차적 매크로를 살펴보고 더 복잡한 코드 생성을 수행합니다. 브라우저에서 직접 실행하는 실습 코드로 Learn Rust Coding을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Learn Rust Coding을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Learn Rust Coding은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 2번째 강의입니다.

“절차적 매크로: Derive, Function” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Learn Rust Coding 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Learn Rust Coding 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 선언적 매크로(`macro_rules!`)
  2. 절차적 매크로: Derive, Function
  3. 안전하지 않은 Rust와 상호 작용하기
← Learn Rust Coding(으)로 돌아가기