Rust 튜토리얼 목차

매크로(Macros)

Rust의 매크로 시스템은 코드를 생성하고 추상화하는 강력한 방법을 제공합니다.

a. 매크로의 개념 및 사용 사례

매크로는 코드를 생성하거나 특정 패턴에 따라 코드를 변형하는 데 사용되는 메타 프로그래밍 기술입니다.

Rust에서는 매크로를 사용하여 코드 중복을 줄이고, 가독성을 향상시키며, 유연한 추상화를 구현할 수 있습니다.

매크로는 주로 컴파일 시간에 코드를 생성하거나 수정하는 작업에 사용됩니다. (ex. println!)

b. 선언형 매크로(Declarative Macros) 생성하기

선언형 매크로는 매크로 규칙을 사용하여 코드를 생성하는 매크로입니다.

macro_rules! 키워드를 사용하여 선언형 매크로를 정의할 수 있습니다.

macro_rules! vec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

fn main() {
    let v = vec![1, 2, 3];
    println!("v: {:?}", v);
}

c. 프로시저 매크로(Procedural Macros) 생성하기

프로시저 매크로는 Rust의 컴파일러에 플러그인으로 동작하는 함수입니다.

프로시저 매크로는 주로 속성(attribute)에 사용되며, 소스 코드를 받아 변형된 소스 코드를 반환합니다.

프로시저 매크로를 정의하려면 proc_macro 라이브러리를 사용하고, 별도의 크레이트로 구성해야 합니다.

// 프로시저 매크로를 정의하는 크레이트입니다.
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    let name = &ast.ident;
    let gen = quote! {
        impl HelloMacro for #name {
            fn hello_macro() {
                println!("안녕하세요, 여기는 {}입니다.", stringify!(#name));
            }
        }
    };
    gen.into()
}
// 프로시저 매크로를 사용하는 크레이트입니다.
use hello_macro::HelloMacro;
use hello_macro_derive::HelloMacro;

#[derive(HelloMacro)]
struct Pancakes;

fn main() {
    Pancakes::hello_macro();
}

d. 매크로 규칙 및 패턴 매칭

Rust의 매크로는 패턴 매칭을 통해 매개 변수를 추출하고, 규칙에 따라 코드를 생성합니다.

매크로에서 패턴 매칭을 사용하려면 다음 구문을 사용합니다.

또한, 매크로에서 사용할 수 있는 반복자 구문도 있습니다.

macro_rules! create_function {
    ($func_name:ident) => (
        fn $func_name() {
            println!("함수 {}가 호출되었습니다.", stringify!($func_name));
        }
    );
}

create_function!(foo);
create_function!(bar);

fn main() {
    foo();
    bar();
}

이렇게 매크로를 사용하여 코드 생성 및 추상화를 구현하면, 유연한 프로그래밍을 할 수 있고, 가독성 및 유지보수성을 높일 수 있습니다.

매크로의 핵심은 패턴 매칭과 규칙을 통해 코드를 재사용하고, 확장성을 높이는 것입니다.