Macro pratiche
Casi d'uso
Macro pratiche è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Le macro nel mondo reale
Oltre gli esempi didattici, le macro risolvono problemi concreti: catturare il contesto del codice sorgente, derivare type class, validare valori letterali e generare codice senza boilerplate.
Caso d'uso: assert con messaggio
Una macro può catturare il testo sorgente di una condizione fallita per produrre automaticamente un messaggio utile per l'asserzione.
import scala.quoted.*
inline def myAssert(inline cond: Boolean): Unit =
${ assertImpl('cond) }Catturare il codice sorgente
All'interno della macro, cond.show (tramite l'API reflect) restituisce il codice sorgente letterale dell'espressione, che può essere inserito nel messaggio di errore.
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 }) }
}Caso d'uso: validazione in fase di compilazione
Validi un valore letterale, ad esempio una regex o un numero di porta, in fase di compilazione, così i valori non validi non arrivano mai a runtime.
import scala.quoted.*
inline def port(inline n: Int): Int = ${ portImpl('n) }Interrompere l'elaborazione per input non valido
Estragga il valore letterale, lo verifichi e chiami report.errorAndAbort per i valori non validi, trasformando un bug a runtime in un errore di compilazione.
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
}Caso d'uso: derivazione di type class
Le macro, spesso tramite inline + scala.deriving.Mirror, possono generare istanze di type class, come encoder JSON, per qualsiasi case class senza boilerplate.
import scala.deriving.Mirror
trait Show[T] { def show(t: T): String }
inline def derived[T](using Mirror.Of[T]): Show[T] = ???Usare Mirror
Un Mirror espone in fase di compilazione i tipi e le etichette dei campi di un product. In combinazione con inline, consente di iterare sui campi per costruire un'istanza.
import scala.deriving.*
import scala.compiletime.*
inline def labels[T](using m: Mirror.ProductOf[T]): List[String] =
constValueTuple[m.MirroredElemLabels].toList.map(_.toString)Caso d'uso: logging con posizione
Una macro può leggere Position dall'API reflect per associare ai messaggi di log il file e il numero di riga, senza costi a runtime.
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}")
}Quando NON usare le macro
Le macro sono potenti, ma costose da mantenere e sottoporre a debug. Preferisca prima funzioni normali, metodi inline o derivazione con given. Ricorra alle macro solo quando queste soluzioni non sono sufficienti.
Testare le macro
Testi il comportamento generato come farebbe con il codice ordinario e verifichi che gli input non validi non vengano compilati, usando strumenti come typeCheckErrors delle utilità di test in fase di compilazione.
Analogo a runtime
Una macro di validazione in fase di compilazione produce lo stesso effetto di questo controllo autonomo a runtime, ma l'errore si verifica durante la compilazione anziché a 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
}
}Verifica rapida
Qual è il principale vantaggio di validare un valore letterale con una macro invece che a runtime?
Riepilogo
Ha esplorato alcuni casi d'uso pratici delle macro:
assertcon cattura del codice sorgente- validazione in fase di compilazione con
errorAndAbort - derivazione di type class tramite
Mirror - logging con informazioni sulla posizione
- quando evitare le macro e come sottoporle a test
Ha completato il corso di metaprogrammazione e macro.
Domande Frequenti
La lezione «Macro pratiche» è gratuita?
Sì — il testo completo di «Macro pratiche» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Cosa imparerò in «Macro pratiche»?
Casi d'uso Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?
Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Macro pratiche»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?
Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Metodi inline
- Basi delle macro
- Quote e splice
- Macro pratiche