0Pricing
Scala for Backend Engineering & Functional Programming · Lekcja

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:

  • assert przechwytują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

  1. Metody inline
  2. Podstawy makr
  3. Quotes i splices
  4. Praktyczne makra
← Powrót do Scala for Backend Engineering & Functional Programming