0Pricing
Scala for Backend Engineering & Functional Programming · Lekcja

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 Quotes i Expr[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

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