Tutorial by Examples

Macros allow us to abstract syntactical patterns that are repeated many times. For instance: /// Computes `a + b * c`. If any of the operation overflows, returns `None`. fn checked_fma(a: u64, b: u64, c: u64) -> Option<u64> { let product = match b.checked_mul(c) { Some(p) =&...
// This example creates a macro `set!` that functions similarly to the built-in // macro vec! use std::collections::HashSet; macro_rules! set { ( $( $x:expr ),* ) => { // Match zero or more comma delimited items { let mut temp_set = HashSet::new(); // Create a ...
A macro can call itself, like a function recursion: macro_rules! sum { ($base:expr) => { $base }; ($a:expr, $($rest:expr),+) => { $a + sum!($($rest),+) }; } Let's go though the expansion of sum!(1, 2, 3): sum!(1, 2, 3) // ^ ^~~~ // $a $rest => 1 + sum!(2, 3)...
A macro can produce different outputs against different input patterns: /// The `sum` macro may be invoked in two ways: /// /// sum!(iterator) /// sum!(1234, iterator) /// macro_rules! sum { ($iter:expr) => { // This branch handles the `sum!(iterator)` case $iter.f...
In $e:expr, the expr is called the fragment specifier. It tells the parser what kind of tokens the parameter $e is expecting. Rust provides a variety of fragment specifiers to, allowing the input to be very flexible. SpecifierDescriptionExamplesidentIdentifierx, foopathQualified namestd::collection...
Exporting a macro to allow other modules to use it: #[macro_export] // ^~~~~~~~~~~~~~~ Think of it as `pub` for macros. macro_rules! my_macro { (..) => {..} } Using macros from other crates or modules: #[macro_use] extern crate lazy_static; // ^~~~~~~~~~~~ Must add this in ord...
(All of these are unstable, and thus can only be used from a nightly compiler.) log_syntax!() #![feature(log_syntax)] macro_rules! logged_sum { ($base:expr) => { { log_syntax!(base = $base); $base } }; ($a:expr, $($rest:expr),+) => { { log_syntax!(a = $...

Page 1 of 1