Введение
В этом лабораторном задании мы исследуем мощную макросную систему, предоставляемую Rust, которая позволяет выполнять метапрограммирование путём расширения макросов в абстрактные синтаксические деревья. Макрос macro_rules! используется для создания макросов, и они отличаются от функций наличием восклицательного знака ! в конце. Макросы полезны для избежания дублирования кода, создания доменных языков и определения вариативных интерфейсов для функций, которые могут принимать переменное количество аргументов.
Примечание: Если в лабораторном задании не указано имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать
main.rs, скомпилировать и запустить его с помощьюrustc main.rs &&./main.
macro_rules!
Rust предоставляет мощную макросную систему, которая позволяет выполнять метапрограммирование. Как вы видели в предыдущих главах, макросы похожи на функции, за исключением того, что их имя заканчивается восклицательным знаком !, но вместо генерации вызова функции макросы расширяются в исходный код, который компилируется вместе с остальной программой. Однако, в отличие от макросов в C и других языках, макросы Rust расширяются в абстрактные синтаксические деревья, а не в строку для препроцессинга, поэтому вы не получаете неожиданных ошибок приоритета.
Макросы создаются с использованием макроса macro_rules!.
// Это простой макрос с именем `say_hello`.
macro_rules! say_hello {
// `()` указывает, что макрос не принимает аргументов.
() => {
// Макрос будет расширён в содержимое этого блока.
println!("Hello!")
};
}
fn main() {
// Этот вызов будет расширён в `println!("Hello")`
say_hello!()
}
Так почему макросы полезны?
Не повторяйте себя. В многих случаях вам может потребоваться похожая функциональность в нескольких местах, но с разными типами. Чаще всего написание макроса — это полезный способ избежать повторения кода. (Подробнее об этом позже)
Доменные языки. Макросы позволяют вам определить специальный синтаксис для конкретной цели. (Подробнее об этом позже)
Вариативные интерфейсы. Иногда вы хотите определить интерфейс, который принимает переменное количество аргументов. Например,
println!, который может принимать любое количество аргументов, в зависимости от строки формата. (Подробнее об этом позже)
Резюме
Поздравляем! Вы завершили лабораторную работу по Macro_rules! Вы можете выполнить больше лабораторных работ в LabEx, чтобы улучшить свои навыки.