Praktyczne makra
Zastosowania
Praktyczne makra to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 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.
Makra w praktyce
Poza przykładami demonstracyjnymi makra rozwiązują konkretne problemy: przechwytują kontekst źródłowy, wyprowadzają instancje type class, sprawdzają literały i generują kod bez powtarzalnego szablonu.
Przypadek użycia: assert z komunikatem
Makro może przechwycić tekst źródłowy niespełnionego warunku, aby automatycznie utworzyć pomocny komunikat asercji.
import scala.quoted.*
inline def myAssert(inline cond: Boolean): Unit =
${ assertImpl('cond) }Przechwytywanie kodu źródłowego
Wewnątrz makra cond.show (za pośrednictwem API refleksji) zwraca dosłowny kod źródłowy wyrażenia, który można wstawić do komunikatu o błędzie.
import scala.quoted.*
def assertImpl(cond: Expr[Boolean])(using q: Quotes): Expr[Unit] = {
import q.reflect.*
val src = Expr(cond.asTerm.show)
'{ if (!${ cond }) throw new AssertionError("failed: " + ${ src }) }
}Przypadek użycia: walidacja w czasie kompilacji
Weryfikuj literał (na przykład wyrażenie regularne lub numer portu) w czasie kompilacji, aby nieprawidłowe wartości nigdy nie trafiły do czasu działania.
import scala.quoted.*
inline def port(inline n: Int): Int = ${ portImpl('n) }Przerywanie działania dla nieprawidłowych danych
Wyodrębnij literał, sprawdź go i wywołaj report.errorAndAbort dla nieprawidłowych wartości — zamieniając błąd w czasie działania na błąd kompilacji.
import scala.quoted.*
def portImpl(n: Expr[Int])(using q: Quotes): Expr[Int] = {
import q.reflect.*
val v = n.valueOrAbort
if (v < 1 || v > 65535) report.errorAndAbort("invalid port")
n
}Przypadek użycia: wyprowadzanie type class
Makra (często za pomocą inline + scala.deriving.Mirror) mogą generować instancje type class, takie jak kodery JSON, dla dowolnej klasy case bez konieczności pisania kodu pomocniczego.
import scala.deriving.Mirror
trait Show[T] { def show(t: T): String }
inline def derived[T](using Mirror.Of[T]): Show[T] = ???Korzystanie z Mirror
Mirror udostępnia typy pól i ich etykiety dla produktu w czasie kompilacji. W połączeniu z inline można iterować po polach, aby zbudować instancję.
import scala.deriving.*
import scala.compiletime.*
inline def labels[T](using m: Mirror.ProductOf[T]): List[String] =
constValueTuple[m.MirroredElemLabels].toList.map(_.toString)Przypadek użycia: logowanie z pozycją
Makro może odczytać Position z API refleksji i dołączyć do komunikatów dziennika nazwę pliku oraz numer wiersza bez kosztu w czasie działania.
import scala.quoted.*
def posImpl(using q: Quotes): Expr[String] = {
import q.reflect.*
val p = Position.ofMacroExpansion
Expr(s"${p.sourceFile.name}:${p.startLine + 1}")
}Kiedy NIE używać makr
Makra są potężne, ale kosztowne w utrzymaniu i debugowaniu. Najpierw należy rozważyć zwykłe funkcje, metody inline lub wyprowadzanie za pomocą given. Po makra warto sięgać dopiero wtedy, gdy te rozwiązania nie potrafią wyrazić wymaganej funkcjonalności.
Testowanie makr
Należy testować zachowanie wygenerowanego kodu tak jak zwykły kod oraz sprawdzać, czy nieprawidłowe dane nie przechodzą kompilacji, używając narzędzi takich jak typeCheckErrors z narzędzi testowych czasu kompilacji.
Analog czasu wykonywania
Makro walidujące w czasie kompilacji daje taki sam efekt jak ta samodzielna kontrola wykonywana w czasie działania — jednak błąd występuje podczas kompilacji, a nie w czasie wykonywania programu.
object Main {
def port(n: Int): Int = {
require(n >= 1 && n <= 65535, "invalid port")
n
}
def main(args: Array[String]): Unit = {
println(port(8080)) // 8080
}
}Szybkie sprawdzenie
Jaka jest główna zaleta walidowania literału za pomocą makra zamiast w czasie działania?
Podsumowanie
Przeanalizował(a) Pan(i) praktyczne zastosowania makr:
assertprzechwytujący kod źródłowy- walidacja w czasie kompilacji za pomocą
errorAndAbort - wyprowadzanie type class za pomocą
Mirror - logowanie uwzględniające pozycję
- kiedy unikać makr i jak je testować
Ukończył(a) Pan(i) kurs Metaprogramowanie i makra.
Często zadawane pytania
Czy lekcja „Praktyczne makra” jest bezpłatna?
Tak — pełny tekst „Praktyczne makra” 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 „Praktyczne makra”?
Zastosowania Ć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 4 z 4.
Ile czasu zajmuje lekcja „Praktyczne makra”?
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