⚙️ Процедурные макросы в Rust


На главную > Блог > Категория > ⚙️ Процедурные макросы в Rust

книги по трейдингу

Процедурные макросы в Rust

Rust procedural macros metaprogramming custom derive proc-macro

Процедурные макросы — одна из самых мощных фич Rust. Они позволяют не просто генерировать код по шаблону, а анализировать синтаксическую структуру Rust-кода на этапе компиляции и изменять её или расширять [citation:8]. В отличие от декларативных макросов (macro_rules!), которые работают как «умная замена» по шаблонам, процедурные макросы — это полноценные Rust-функции, которые принимают на вход поток токенов (TokenStream) и возвращают новый поток токенов [citation:1][citation:6][citation:8].

1. 🏗️ Три вида процедурных макросов

Процедурные макросы делятся на три типа, которые различаются только синтаксисом вызова и тем, что они обрабатывают на входе [citation:6][citation:8].

💡 Главное преимущество: Процедурный макрос — это обычная Rust-функция. Вы можете анализировать входной код с помощью syn, формировать новый код с помощью quote и даже отлаживать генерацию с помощью cargo expand [citation:3][citation:6].

2. ⚙️ Создание первого custom derive-макроса

Процедурные макросы всегда живут в отдельном крейте, который должен быть помечен как proc-macro в Cargo.toml [citation:1][citation:6][citation:8].


[lib]
proc-macro = true

[dependencies]
syn = { version = "2", features = ["full", "derive"] }
quote = "1"

В коде самого макроса используется базовая структура [citation:3][citation:6]:


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!("Hello, Macro! My name is {}", stringify!(#name));
            }
        }
    };
    gen.into()
}
🧪 Как это работает:
  • parse_macro_input! — разбирает входной поток токенов в структуру AST с помощью syn [citation:3][citation:6].
  • quote! — формирует новый код, подставляя значения из переменных через #name [citation:3][citation:6].
  • stringify!(#name) — превращает имя типа в строку для вывода [citation:3].

3. 🧐 Обработка атрибутов и паника вместо ошибок

Если ваш макрос должен принимать пользовательские атрибуты, их нужно явно перечислить в атрибуте proc_macro_derive [citation:3].


#[proc_macro_derive(HelloMacro, attributes(HelloMacroName))]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    // ... разбор атрибута HelloMacroName
}
⚠️ Важно: Если макрос сталкивается с ошибкой (например, пользователь применил derive к enum, а макрос работает только со структурами), используйте panic! с понятным сообщением [citation:3]. Компилятор перехватит панику и покажет её как ошибку компиляции.

Более продвинутый способ — использовать syn::Error с правильной привязкой к позиции в коде [citation:6].

4. 🧰 Продвинутые практики

📌 Примечание: Процедурные макросы — это мощный инструмент, но их применение увеличивает время компиляции и усложняет читаемость кода. Используйте их, когда без них действительно не обойтись: для автоматической генерации boilerplate кода, реализации трейтов или создания DSL [citation:9].

🎯 Итог

Процедурные макросы — это «кузница» кода в Rust. Они позволяют делать с кодом то, что на других языках требует тяжеловесных кодогенераторов. Связка proc_macro + syn + quote даёт разработчикам возможность анализировать и генерировать код прямо во время компиляции, а cargo expand и trybuild — отлаживать этот процесс [citation:3][citation:6].

Материалы для углублённого изучения: книга «Write Powerful Rust Macros» Сэма Ван Овермейра (Manning, 2024) полностью посвящена этой теме — от первых шагов до проектирования DSL и публикации собственных макросов [citation:9].


Статья создана для образовательных целей. Код из примеров приведён в упрощённом виде и не является готовым к использованию в продакшене.

 

Дата размещения статьи: 26-07-2026 в 13:41:29