Basi delle macro
Codice in fase di compilazione
Basi delle macro è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 2 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.
Che cos'è una macro?
Una macro è codice che viene eseguito a tempo di compilazione per generare altro codice. Le macro di Scala 3 consentono di ispezionare gli argomenti, costruire espressioni e inserirle nel programma prima della compilazione.
Schema inline + macro
Una macro viene invocata da un inline def che delega a un metodo contrassegnato con ${ ... }. L'inline def è l'API pubblica; l'implementazione della macro viene eseguita dal compilatore.
import scala.quoted.*
inline def power(x: Double, inline n: Int): Double =
${ powerImpl('x, 'n) }Il contesto Quotes
Ogni implementazione di macro riceve un contesto implicito Quotes. Esso fornisce accesso all'API di reflection e la possibilità di costruire e inserire espressioni.
import scala.quoted.*
def powerImpl(x: Expr[Double], n: Expr[Int])(using Quotes): Expr[Double] =
???Expr[T]
Expr[T] rappresenta un'espressione tipizzata di tipo T come dato a tempo di compilazione. Le macro ricevono e restituiscono valori Expr.
Elevare valori a Expr
Expr(value) eleva un valore di runtime calcolato nella macro a un'espressione da reinserire. Funziona per qualsiasi tipo con un'istanza di ToExpr.
import scala.quoted.*
def constImpl(using Quotes): Expr[Int] = Expr(42)Estrarre argomenti costanti
n.value (o n.valueOrAbort) estrae la costante contenuta in un Expr quando l'argomento è noto staticamente, consentendo alla macro di scegliere un ramo in base a essa.
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
}Segnalazione degli errori
Usi quotes.reflect.report.errorAndAbort per emettere un errore di compilazione con messaggio e posizione quando i prerequisiti della macro non sono soddisfatti.
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)
}Dove risiedono le macro
Le implementazioni delle macro devono essere compilate prima del codice che le usa, in genere in un file o modulo separato. Il compilatore le esegue durante la compilazione del chiamante.
Casi d'uso comuni
Le macro consentono:
- la derivazione di typeclass (codec JSON e così via)
- la convalida a tempo di compilazione (regex, SQL)
- il logging che cattura le posizioni nel codice sorgente
- astrazioni a costo zero
Sicurezza e igiene
Le macro di Scala 3 sono hygienic: gli identificatori generati non possono catturare accidentalmente le variabili dell'utente e il sistema dei tipi verifica il codice generato, prevenendo molti bug classici delle macro.
Equivalente a runtime
Una macro che calcola una potenza a tempo di compilazione produce lo stesso risultato di questa versione autosufficiente a runtime, ma con le moltiplicazioni incorporate dal compilatore.
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
}
}Verifica rapida
Quale tipo rappresenta un'espressione tipizzata a tempo di compilazione che le macro ricevono e restituiscono?
Riepilogo
Ha appreso i fondamenti delle macro:
- le macro vengono eseguite a tempo di compilazione tramite lo schema
inline def ... ${ } - il contesto
QuoteseExpr[T] - l'elevamento con
Expr(...)e l'estrazione con.value - segnalazione degli errori e igiene
Prossimo argomento: quotes e splice.
Domande Frequenti
La lezione «Basi delle macro» è gratuita?
Sì — il testo completo di «Basi delle macro» è 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 «Basi delle macro»?
Codice in fase di compilazione 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 2 di 4.
Quanto tempo richiede la lezione «Basi delle macro»?
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