Podstawy makr
Kod wykonywany podczas kompilacji
Podstawy makr to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 2 z 4. 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 Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Czym jest makro?
Makro to kod uruchamiany podczas kompilacji w celu wygenerowania innego kodu. Makra w Scali 3 pozwalają analizować argumenty, budować wyrażenia i wstawiać je do programu przed jego skompilowaniem.
Wzorzec Inline + Macro
Makro jest wywoływane z poziomu inline def, który deleguje wykonanie do metody oznaczonej za pomocą ${ ... }. Inline def stanowi publiczne API, a implementacja makra działa w kompilatorze.
import scala.quoted.*
inline def power(x: Double, inline n: Int): Double =
${ powerImpl('x, 'n) }Kontekst Quotes
Każda implementacja makra przyjmuje niejawny kontekst Quotes. Zapewnia on dostęp do API refleksji oraz możliwość budowania i wstawiania wyrażeń.
import scala.quoted.*
def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] =
???Expr[T]
Expr[T] reprezentuje typowane wyrażenie typu T jako dane znane podczas kompilacji. Makra otrzymują i zwracają wartości typu Expr.
Podnoszenie wartości do Expr
Expr(value) podnosi wartość obliczoną w czasie działania makra do wyrażenia, które można ponownie wstawić. Działa to dla każdego typu z instancją ToExpr.
import scala.quoted.*
def constImpl(using Quotes): Expr[Int] = Expr(42)Wyodrębnianie stałych argumentów
n.value (lub n.valueOrAbort) wyodrębnia stałą ukrytą za Expr, gdy argument jest znany statycznie, dzięki czemu makro może podjąć na jej podstawie decyzję.
import scala.quoted.*
def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] = {
val exp = n.valueOrAbort
??? // build x*x*...*x exp times
}Zgłaszanie błędów
Użyj quotes.reflect.report.errorAndAbort, aby zgłosić błąd kompilacji z komunikatem i lokalizacją, gdy warunki wstępne makra nie są spełnione.
import scala.quoted.*
def check(n: Expr[Int])(using q: Quotes): Expr[Int] = {
import q.reflect.*
val v = n.valueOrAbort
if (v < 0) report.errorAndAbort("must be >= 0")
Expr(v)
}Gdzie znajdują się makra
Implementacje makr muszą zostać skompilowane przed kodem, który ich używa — zazwyczaj znajdują się w osobnym pliku lub module. Kompilator wykonuje je podczas kompilowania kodu wywołującego.
Typowe zastosowania
Makra obsługują:
- wyprowadzanie instancji typeclass (np. kodeków JSON)
- sprawdzanie podczas kompilacji (wyrażeń regularnych, SQL)
- rejestrowanie informacji obejmujących pozycje w kodzie źródłowym
- bez-kosztowe abstrakcje
Bezpieczeństwo i higiena
Makra w Scali 3 są higieniczne: generowane identyfikatory nie mogą przypadkowo przechwycić zmiennych użytkownika, a system typów sprawdza wygenerowany kod, zapobiegając wielu klasycznym błędom makr.
Odpowiednik wykonywany w czasie działania
Makro obliczające potęgę podczas kompilacji daje taki sam wynik jak ten samodzielny odpowiednik wykonywany w czasie działania — jednak kompilator wbudowuje w nim mnożenia.
object Main {
def power(x: Double, n: Int): Double =
if (n == 0) 1.0 else x * power(x, n - 1)
def main(args: Array[String]): Unit = {
println(power(2.0, 3)) // 8.0
}
}Szybkie sprawdzenie
Jaki typ reprezentuje typowane wyrażenie znane podczas kompilacji, które makra otrzymują i zwracają?
Podsumowanie
Uczestnik poznał podstawy makr:
- makra działają podczas kompilacji za pomocą wzorca
inline def ... ${ } - kontekst
QuotesiExpr[T] - podnoszenie za pomocą
Expr(...)i wyodrębnianie za pomocą.value - zgłaszanie błędów i higiena
Następnie: quotes i splices.
Często zadawane pytania
Czy lekcja „Podstawy makr” jest bezpłatna?
Tak — pełny tekst „Podstawy makr” 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 Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Podstawy makr”?
Kod wykonywany podczas kompilacji Ćwiczysz Scala for Backend Engineering & Functional Programming 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ąć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming 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 2 z 4.
Ile czasu zajmuje lekcja „Podstawy makr”?
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 Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming 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
- Metody inline
- Podstawy makr
- Quotes i splices
- Praktyczne makra