0Pricing
Learn Rust Coding · Lekcja

Makra deklaratywne (`macro_rules!`)

Nauczą się Państwo pisać makra deklaratywne służące do abstrakcji powtarzalnych wzorców kodu i generowania kodu podczas kompilacji.

Makra deklaratywne (`macro_rules!`) to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 1 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.

Czym są makra w Rust?

Makra pozwalają pisać kod, który tworzy kod! Przypominają funkcje, ale operują na drzewach składniowych (strukturze kodu), a nie na wartościach.

  • Pomagają abstrahować powtarzalny kod.
  • Umożliwiają tworzenie języków dziedzinowych (DSL) wewnątrz Rusta.
  • Są wykonywane podczas kompilacji i przed właściwą kompilacją rozwijają się do zwykłego kodu Rust.

Składnia makr deklaratywnych

Deklaratywne makra Rusta używają słowa kluczowego macro_rules!. Definiują zestaw reguł dopasowujących określone wzorce kodu Rust.

Można traktować je jak dopasowywanie wzorców dla fragmentów kodu. Gdy kompilator napotka wywołanie makra, próbuje dopasować dane wejściowe do jednej ze zdefiniowanych reguł.

Pierwsze makro `macro_rules!`

Utwórzmy bardzo proste makro wyświetlające powitanie. Proszę zwrócić uwagę na słowo kluczowe macro_rules! oraz składnię () => {}, która definiuje regułę bez wzorca danych wejściowych.

Proszę uruchomić ten przykład:

macro_rules! greet {
    () => {
        println!("Hello from a macro!");
    };
}

fn main() {
    greet!(); // Call our macro!
}

Przechwytywanie danych wejściowych za pomocą oznaczników

Makra mogą przyjmować dane wejściowe za pomocą „oznaczników”. Informują one makro, jakiego rodzaju składni Rust powinno oczekiwać i którą przechwycić.

  • $expr: wyrażenie (np. 1 + 2, "hello")
  • $ident: identyfikator (np. nazwa zmiennej lub funkcji)
  • $ty: typ (np. i32, String)
  • $block: blok kodu (np. { ... })
  • ...i wiele innych!

Makra przyjmujące argumenty

Oto makro, które przyjmuje wyrażenie ($e:expr) i wyświetla jego wartość. :expr jest oznacznikiem.

Przechwycone $e staje się następnie dostępne w ciele makra. Makro stringify! przekształca wyrażenie w jego reprezentację tekstową.

macro_rules! debug_print {
    ($e:expr) => {
        println!("Debug: {} = {:?}", stringify!($e), $e);
    };
}

fn main() {
    let x = 10;
    debug_print!(x + 5);
    debug_print!("Rust macros are fun");
}

Obsługa wielu danych wejściowych

Co zrobić, jeśli chcesz, aby makro przyjmowało wiele argumentów tego samego typu? Możesz użyć operatorów powtórzeń: $()*.

  • $(): zawartość wewnątrz określa wzorzec do powtórzenia.
  • *: zero lub więcej powtórzeń.
  • +: jedno lub więcej powtórzeń.
  • Możesz także określić separator, na przykład $(...),* dla elementów oddzielonych przecinkami.

Makro z powtarzającymi się argumentami

Utwórzmy makro, które przyjmuje wiele wyrażeń oddzielonych przecinkami i wyświetla każde z nich osobno. Jest to przydatne podczas tworzenia struktur przypominających listy.

macro_rules! print_all {
    ( $( $x:expr ),* ) => {
        $( // This $(...)* repeats the `println!` call
            println!("Item: {:?}", $x);
        )*
    };
}

fn main() {
    print_all!(1, "hello", true, 3.14);
    print_all!("Just one item");
}

Zrozumienie higieny makr

Makra w Rust są „higieniczne”. Oznacza to, że zmienne zdefiniowane wewnątrz makra nie będą przypadkowo kolidować ze zmiennymi spoza makra, nawet jeśli mają taką samą nazwę.

Podczas rozwijania makra kompilator wewnętrznie zmienia nazwy elementów, aby zapobiec niezamierzonym efektom ubocznym. Dzięki temu makra są bezpieczniejsze i bardziej przewidywalne w użyciu.

Jak debugować makra

Czasami makra nie rozwijają się zgodnie z oczekiwaniami. Rust udostępnia sposób wyświetlania rozwiniętego kodu:

  • Uruchom cargo expand (wymaga zainstalowania narzędzia cargo-expand).
  • Użyj bezpośrednio rustc --pretty expanded dla pliku źródłowego.

Pokazuje to surowy kod Rust generowany przez makro, co jest niezwykle pomocne podczas debugowania i zrozumienia złożonego działania makr!

Quiz: dopasowywanie wzorców makr

Rozważ następującą definicję makra:

macro_rules! make_tuple {
    ( $x:expr, $y:expr ) => {
        ($x, $y)
    };
}

Która z poniższych linii poprawnie się skompiluje i użyje makra make_tuple!?

Podsumowanie: makra deklaratywne

W tej lekcji poznali Państwo makra deklaratywne korzystające z macro_rules!:

  • Generują kod w czasie kompilacji, abstrahując powtarzalne wzorce.
  • Używają dopasowywania wzorców do przechwytywania danych wejściowych na podstawie składni.
  • Specyfikatory, takie jak $expr i $ident, określają oczekiwany rodzaj składni.
  • Operatory powtórzeń, takie jak $()*, obsługują wiele argumentów z elastycznymi separatorami.
  • Makra są higieniczne, dzięki czemu zapobiegają przypadkowym konfliktom nazw.

Makra to potężne narzędzie do ograniczania powtarzalnego kodu oraz tworzenia elastycznych i wygodnych interfejsów API w Rust!

Często zadawane pytania

Czy lekcja „Makra deklaratywne (`macro_rules!`)” jest bezpłatna?

Tak — pełny tekst „Makra deklaratywne (`macro_rules!`)” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.

Co nauczysz się w „Makra deklaratywne (`macro_rules!`)”?

Nauczą się Państwo pisać makra deklaratywne służące do abstrakcji powtarzalnych wzorców kodu i generowania kodu podczas kompilacji. Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 3.

Ile czasu zajmuje lekcja „Makra deklaratywne (`macro_rules!`)”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Makra deklaratywne (`macro_rules!`)
  2. Makra proceduralne: Derive, Function
  3. Praca z Rust w trybie unsafe
← Powrót do Learn Rust Coding