Praktiske makroer
Bruksområder
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:
assertsom 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.
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
- Inline-metoder
- Grunnleggende makroer
- Quotes og splices
- Praktiske makroer