0Pricing
Scala for Backend Engineering & Functional Programming · Lección

Macros prácticas

Casos de uso

Macros prácticas es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

Las macros en el mundo real

Más allá de los ejemplos sencillos, las macros resuelven problemas concretos: capturar el contexto del código fuente, derivar typeclasses, validar literales y generar código sin código repetitivo.

Caso de uso: assert con mensaje

Una macro puede capturar el texto del código fuente de una condición fallida para producir automáticamente un mensaje útil de aserción.

import scala.quoted.*

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

Captura del código fuente

Dentro de la macro, cond.show (mediante la API de reflexión) proporciona el código fuente literal de la expresión, que puede insertar en el mensaje de error.

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 de uso: validación en tiempo de compilación

Valide un literal, como una expresión regular o un número de puerto, en tiempo de compilación para impedir que los valores no válidos lleguen al tiempo de ejecución.

import scala.quoted.*

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

Interrupción ante entradas no válidas

Extraiga el literal, compruébelo y llame a report.errorAndAbort para los valores no válidos; así convertirá un error de ejecución en un error de compilación.

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 de uso: derivación de typeclasses

Las macros (a menudo mediante inline + scala.deriving.Mirror) pueden generar instancias de typeclasses, como codificadores JSON, para cualquier case class sin código repetitivo.

import scala.deriving.Mirror

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

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

Uso de Mirror

Un Mirror expone en tiempo de compilación los tipos y las etiquetas de los campos de un producto. Combinado con inline, permite iterar sobre los campos para construir una instancia.

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

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

Caso de uso: registro con posición

Una macro puede leer Position de la API de reflexión para añadir el archivo y el número de línea a los mensajes de registro sin coste en tiempo de ejecución.

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

Cuándo NO usar macros

Las macros son potentes, pero su mantenimiento y depuración resultan costosos. Prefiera primero las funciones normales, los métodos inline o la derivación mediante given. Recurra a las macros solo cuando esas opciones no permitan expresar lo que necesita.

Pruebas de macros

Pruebe el comportamiento generado como cualquier código normal y compruebe que las entradas no válidas no compilen mediante herramientas como typeCheckErrors de las utilidades de pruebas en tiempo de compilación.

Análogo en tiempo de ejecución

Una macro de validación en tiempo de compilación produce el mismo efecto que esta comprobación autónoma en tiempo de ejecución, pero el error se produce durante la compilación en lugar de durante la ejecución.

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

Comprobación rápida

¿Cuál es la principal ventaja de validar un literal con una macro en lugar de hacerlo en tiempo de ejecución?

Resumen

Ha explorado casos de uso prácticos de las macros:

  • assert que captura el código fuente
  • validación en tiempo de compilación con errorAndAbort
  • derivación de typeclasses mediante Mirror
  • registro con información de posición
  • cuándo evitar las macros y cómo probarlas

Ha completado el curso de Metaprogramación y macros.

Preguntas frecuentes

¿La lección «Macros prácticas» es gratis?

Sí — el texto completo de «Macros prácticas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

¿Qué aprenderé en «Macros prácticas»?

Casos de uso Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?

No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Macros prácticas»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?

Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Métodos inline
  2. Conceptos básicos de macros
  3. Quotes y splices
  4. Macros prácticas
← Volver a Scala for Backend Engineering & Functional Programming