[Программирование, Rust] Макросы в Rust. macro_rules

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
03-Апр-2021 01:31

Я долго откладывал этот день, но вечно откладывать было нельзя. Что ж, время пришло. Пора наконец разобраться с макросами в Rust. Ну или хотя бы начать.
Давайте сразу определимся, зачем вы хотите их использовать. Макросы - это про метапрограммирование и, можно даже сказать отчасти про reflective программирование. Я, конечно, не разработчик паттернов и стандартов, но использовать макрос (объявленный macro_rules!) как замену функции, как по мне, плохая идея. Во-первых, потому, что функция принимает переменные конкретного типа, а макрос, который принимает переменную, банально не знает её типа, соответственно, понять смысл операций можно только по названию и по самой сигнатуре макроса. А синтаксис макросов не то чтобы очень очевиден…Но, надеюсь, благодаря этой статье он станет более понятен для вас.Что за зверь такой, macro_rules!?Давайте начнём с самого простого. macro_rules! - наш путь к написанию макросов, встроенный прямо в стандартную библиотеку. Давайте начнём с простого примера - макрос, который делает то же, что и unwrap. Это, конечно, невероятно глупая и плохая идея, но для примера подойдёт.Обратите внимание, что макрос объявлен до вызова.Проверить:macro_rules! uncover{    ($var:ident) => {        match $var{            Some(t) => t,            None => panic!("None value")        }    }}fn main(){    let x = Some(2i32);    let unwrapped = uncover!(x);    println!("{}", unwrapped);}Ну-с… давайте разбираться. Что же мы сделали? Перво-наперво, мы объявили макрос uncover: macro_rules! uncoverКоторый принимает переменную $var типа ident. Вообще говоря, ident это не только переменная, но и название функции. Полный список типов, которые можно передать как аргумент в макрос можнопоглядеть тут.В каком-то смысле, вы передаёте в макрос не переменную, а код. Все, что знает макрос про $var - это название того, что мы передали в uncover (в нашем случае, х).Далее идёт код, который вполне себе похож на нативный Rust код, однако есть момент, который бросается в глаза: мы используем переменную со знаком доллара. Итак, что же сделает этот макрос при вызове? Он вставит всю сигнатуру на то место, где вы его вызываете. То есть по сути в рантайме код будет выглядеть не так:let unwrapped = uncover!(x);А так:let unwrapped = match x{    Some(t) => t,    None => panic!(“None value”)};Использовать макросы как обычные функции - плохая идея. Они делают не то же самое, что функции (хотя чем-то похоже на inline-фуннции). И хоть код let x = 2i32;let unwrapped = uncover!(x);не скомпилируется, лучше использовать старые-добрые функции. Всё-таки, они более явные и отлично выполняют цель, с которой были созданы.SummaryИтак, зачем же тебе, простой Иван город Тверь, писать макросы? Да не знаю, сам подумай. Может, есть повторяющееся место в коде, под которое идеально подойдёт макрос? Или ты написал нереальную реализацию списка со скоростью работы O(1) и хочешь инициализировать его вот так: list![1,2,3] ? Ну или тебе просто нравится заниматься метапрограммированием? Правда, последнее трудно вяжется с macro_rules! Всё-таки, в языке есть более мощное метапрограммирование, тёмная магия proc_macro, syn, qoute и TokenTree, но о ней как-нибудь в другой раз.Вот, собственно, и всё. Писать макросы с помощью macro_rules не так-то сложно, главное разобраться в базовых правилах. Может, это сбережёт ваши нервы и/или деньги. Конечно, я не затрагивал в этой статье самое интересное, это наиболее простое из того, что есть. Цель статьи - показать, что макросы - это несложно.Пишите, если хотите статью про proc_macro и syn, там действительно есть на что посмотреть.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_rust, #_rust, #_macro_rules!, #_makros (макрос), #_programmirovanie (
Программирование
)
, #_rust
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 16-Май 04:27
Часовой пояс: UTC + 5