macro_rules!
Rust надає потужну систему макросів, яка дозволяє метапрограмування. Як ви бачили в попередніх розділах, макроси схожі на функції, окрім того, що їхня назва закінчується знаком оклику !, але замість створення виклику функції, макроси розгортаються у вихідний код, який компілюється разом з рештою програми. Однак, на відміну від макросів у C та інших мовах, макроси Rust розгортаються в абстрактні синтаксичні дерева, а не через попередню обробку рядків, тож ви не отримуєте неочікуваних помилок пріоритету.
Макроси створюються за допомогою макроса macro_rules!.
// This is a simple macro named `say_hello`.
macro_rules! say_hello {
// `()` indicates that the macro takes no argument.
() => {
// The macro will expand into the contents of this block.
println!("Hello!")
};
}
fn main() {
// This call will expand into `println!("Hello!")`
say_hello!()
}
То чому макроси корисні?
-
Не повторюйте себе. Є багато випадків, коли вам може знадобитися подібна функціональність у кількох місцях, але з різними типами. Часто написання макроса — це корисний спосіб уникнути повторення коду. (Докладніше про це далі)
-
Предметно-орієнтовані мови. Макроси дозволяють вам визначати спеціальний синтаксис для конкретної мети. (Докладніше про це далі)
-
Варіадичні інтерфейси. Іноді ви хочете визначити інтерфейс, який приймає змінну кількість аргументів. Прикладом є
println!, який може приймати будь-яку кількість аргументів, залежно від рядка формату. (Докладніше про це далі)