0Pricing
Scala for Backend Engineering & Functional Programming · Aula

Macros práticas

Casos de uso.

Macros práticas é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

Macros no mundo real

Além dos exemplos simplificados, as macros resolvem problemas concretos: capturar o contexto do código-fonte, derivar classes de tipos, validar literais e gerar código sem código repetitivo.

Caso de uso: assert com mensagem

Uma macro pode capturar o texto do código-fonte de uma condição que falhou para produzir automaticamente uma mensagem útil de asserção.

import scala.quoted.*

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

Capturando o código-fonte

Dentro da macro, cond.show (por meio da API de reflect) fornece o código-fonte literal da expressão, que você insere na mensagem de erro.

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: validação em tempo de compilação

Valide um literal (como uma expressão regular ou um número de porta) em tempo de compilação, para que valores inválidos nunca cheguem ao tempo de execução.

import scala.quoted.*

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

Interrompendo a execução com entrada inválida

Extraia o literal, verifique-o e chame report.errorAndAbort para valores inválidos — transformando um erro em tempo de execução em um erro de compilação.

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: derivação de classe de tipos

As macros (geralmente por meio de inline + scala.deriving.Mirror) podem gerar instâncias de classes de tipos, como codificadores JSON, para qualquer classe de caso sem 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] = ???

Usando Mirror

Um Mirror expõe os tipos e os rótulos dos campos de um produto em tempo de compilação. Combinado com inline, ele permite iterar pelos campos para criar uma instância.

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 com posição

Uma macro pode ler Position da API de reflect para anexar o arquivo e o número da linha às mensagens de registro, sem custo em tempo de execução.

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 NÃO usar macros

As macros são poderosas, mas custosas de manter e depurar. Prefira primeiro funções comuns, métodos inline ou derivação com given. Recorra às macros somente quando essas alternativas não conseguirem expressar a necessidade.

Testando macros

Teste o comportamento gerado como faria com código comum e teste se as entradas inválidas falham ao compilar usando ferramentas como typeCheckErrors, das utilidades de teste em tempo de compilação.

Análogo em tempo de execução

Uma macro de validação em tempo de compilação produz o mesmo efeito que esta verificação independente em tempo de execução — mas a falha ocorre durante a compilação, e não durante a execução.

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ção rápida

Qual é a principal vantagem de validar um literal com uma macro em vez de fazê-lo durante a execução?

Recapitulação

Você explorou casos de uso práticos de macros:

  • assert com captura do código-fonte
  • validação em tempo de compilação com errorAndAbort
  • derivação de classes de tipos por meio de Mirror
  • registro com reconhecimento de posição
  • quando evitar macros e como testá-las

Você concluiu o curso de Metaprogramação e Macros.

Perguntas Frequentes

A aula “Macros práticas” é grátis?

Sim — o texto completo de “Macros práticas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

O que vou aprender em “Macros práticas”?

Casos de uso. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?

Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Macros práticas”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?

Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Métodos inline
  2. Fundamentos de macros
  3. Quotes e splices
  4. Macros práticas
← Voltar para Scala for Backend Engineering & Functional Programming