Scala for backendutvikling og funksjonell programmering · leksjon

Praktiske makroer

Bruksområder

Leksjon 4 av 413 trinn

Praktiske makroer er en gratis leksjon i Scala for backendutvikling og funksjonell programmering på CoddyKit. Dette er leksjon 4 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Scala for backendutvikling og funksjonell programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Scala for backendutvikling og funksjonell programmering inneholder totalt 4 leksjoner.

Makroer i den virkelige verden

Utover lekeeksempler løser makroer konkrete problemer: å fange opp kildekontekst, derivere typeklasser, validere literaler og generere kode uten boilerplate.

Bruksområde: assert med melding

En makro kan fange opp kildeteksten til en betingelse som feiler, slik at den automatisk kan produsere en nyttig assert-melding.

import scala.quoted.*

inline def myAssert(inline cond: Boolean): Unit =
  ${ assertImpl('cond) }

Fange opp kildekode

Inne i makroen gir cond.show (via reflect-API-et) den bokstavelige kilden til uttrykket, som De splicer inn i feilmeldingen.

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 }) }
}

Bruksområde: validering ved kompilering

Valider en literal (for eksempel et regulært uttrykk eller et portnummer) ved kompilering, slik at ugyldige verdier aldri når runtime.

import scala.quoted.*

inline def port(inline n: Int): Int = ${ portImpl('n) }

Avbryte ved ugyldige inndata

Trekk ut literalen, kontroller den, og kall report.errorAndAbort for ugyldige verdier – slik gjøres en runtime-feil om til en kompileringsfeil.

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
}

Bruksområde: derivering av typeklasser

Makroer (ofte via inline + scala.deriving.Mirror) kan generere typeklasseinstanser, for eksempel JSON-kodere, for enhver case class uten boilerplate.

import scala.deriving.Mirror

trait Show[T] { def show(t: T): String }

inline def derived[T](using Mirror.Of[T]): Show[T] = ???

Bruke Mirror

En Mirror eksponerer felttypene og feltnavnene til et produkt ved kompilering. Kombinert med inline kan De iterere over feltene for å bygge en instans.

import scala.deriving.*
import scala.compiletime.*

inline def labels[T](using m: Mirror.ProductOf[T]): List[String] =
  constValueTuple[m.MirroredElemLabels].toList.map(_.toString)

Bruksområde: logging med posisjon

En makro kan lese Position fra reflect-API-et og legge fil- og linjenummer til loggmeldinger uten runtime-kostnad.

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}")
}

Når De IKKE bør bruke makroer

Makroer er kraftige, men kostbare å vedlikeholde og feilsøke. Foretrekk vanlige funksjoner, inline-metoder eller given-derivering først. Bruk makroer bare når disse ikke kan uttrykke behovet.

Teste makroer

Test den genererte oppførselen som vanlig kode, og test at ugyldige inndata ikke kompilerer ved hjelp av verktøy som typeCheckErrors fra testverktøyene for kompilering.

Runtime-ekvivalent

En makro for validering ved kompilering gir samme effekt som denne selvstendige runtime-kontrollen – men feilen oppstår under kompilering i stedet for ved runtime.

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
  }
}

Rask kontroll

Hva er den viktigste fordelen ved å validere en literal med en makro i stedet for ved runtime?

Oppsummering

De har utforsket praktiske bruksområder for makroer:

  • assert som fanger opp kilde
  • validering ved kompilering med errorAndAbort
  • typeklassederivering via Mirror
  • logging med posisjonsinformasjon
  • når makroer bør unngås, og hvordan de testes

De har fullført kurset Metaprogrammering og makroer.

Gratis å komme i gang

Lær deg Scala med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
39
Leksjoner
143

Ofte stilte spørsmål

Er leksjonen «Praktiske makroer» gratis?

Ja – hele teksten i «Praktiske makroer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Scala for backendutvikling og funksjonell programmering-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Scala for backendutvikling og funksjonell programmering inneholder totalt 4 leksjoner.

Hva lærer jeg i «Praktiske makroer»?

Bruksområder Du øver på Scala for backendutvikling og funksjonell programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Scala for backendutvikling og funksjonell programmering?

Ingen tidligere erfaring er nødvendig. Scala for backendutvikling og funksjonell programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.

Hvor lang tid tar leksjonen «Praktiske makroer»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Scala for backendutvikling og funksjonell programmering-leksjonen?

Ja. Alle Scala for backendutvikling og funksjonell programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Inline-metoder
  2. Grunnleggende makroer
  3. Quotes og splices
  4. Praktiske makroer
← Tilbake til Scala for backendutvikling og funksjonell programmering