0Pricing
Scala for Backend Engineering & Functional Programming · Aula

Correspondência exaustiva

Completude verificada pelo compilador.

Correspondência exaustiva é 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.

O que é correspondência exaustiva?

Uma correspondência é exaustiva quando trata de todos os valores possíveis do tipo correspondente.

Para um trait selado, o compilador conhece todas as variantes e pode verificar se a correspondência cobre todas elas.

Uma correspondência completa

Quando você trata de todas as variantes de um trait selado, o compilador fica satisfeito e nenhum aviso é exibido.

sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
  def name(c: Color): String = c match {
    case Red   => "red"
    case Green => "green"
    case Blue  => "blue"
  }
  def main(args: Array[String]): Unit = {
    println(name(Blue))
  }
}

O compilador está ao seu lado

Se você deixar uma variante de fora, o compilador emitirá um aviso de correspondência não exaustiva durante a compilação.

Isso funciona como uma rede de segurança: você descobre a lacuna antes de executar o programa.

Adicionando uma variante depois

O verdadeiro benefício aparece quando você adiciona uma nova variante. Toda correspondência não exaustiva na sua base de código exibirá um aviso, lembrando você de tratar do novo caso.

Isso torna a refatoração segura e previsível.

Por que evitar um curinga

Adicionar case _ => silencia os avisos de exaustividade. Isso pode ocultar erros quando você adicionar variantes posteriormente.

Para ADTs selados, prefira listar cada variante explicitamente, para que o compilador continue protegendo você.

sealed trait Status
case object Active extends Status
case object Inactive extends Status
object Main {
  def label(s: Status): String = s match {
    case Active   => "on"
    case Inactive => "off"
  }
  def main(args: Array[String]): Unit = {
    println(label(Active))
  }
}

Exaustividade com dados

A exaustividade também se aplica a variantes que carregam dados. Você associa os campos e ainda precisa cobrir todas as variantes.

sealed trait Shape
case class Circle(r: Double) extends Shape
case class Square(s: Double) extends Shape
object Main {
  def area(sh: Shape): Double = sh match {
    case Circle(r) => 3.14159 * r * r
    case Square(s) => s * s
  }
  def main(args: Array[String]): Unit = {
    println(area(Circle(2)))
    println(area(Square(3)))
  }
}

Combinando com guardas

Tenha cuidado: as guardas podem tornar uma correspondência não exaustiva, pois o compilador não consegue provar que elas cobrem todos os valores.

Forneça um caso final sem guarda para a mesma variante, mantendo a exaustividade.

sealed trait Temp
case class Celsius(v: Int) extends Temp
object Main {
  def feel(t: Temp): String = t match {
    case Celsius(v) if v >= 30 => "hot"
    case Celsius(v)            => "not hot"
  }
  def main(args: Array[String]): Unit = {
    println(feel(Celsius(35)))
    println(feel(Celsius(10)))
  }
}

Exaustividade com Option

A Option da biblioteca padrão é um ADT selado com Some e None. Corresponder a ambos torna a correspondência exaustiva.

object Main {
  def show(o: Option[Int]): String = o match {
    case Some(v) => s"value $v"
    case None    => "nothing"
  }
  def main(args: Array[String]): Unit = {
    println(show(Some(7)))
    println(show(None))
  }
}

Exaustividade aninhada

A exaustividade também ajuda com ADTs aninhados. O compilador raciocina sobre cada nível que você destrutura.

sealed trait Tree
case object Leaf extends Tree
case class Node(v: Int, l: Tree, r: Tree) extends Tree
object Main {
  def depth(t: Tree): Int = t match {
    case Leaf          => 0
    case Node(_, l, r) => 1 + math.max(depth(l), depth(r))
  }
  def main(args: Array[String]): Unit = {
    println(depth(Node(1, Leaf, Node(2, Leaf, Leaf))))
  }
}

Por que isso importa

A exaustividade verificada pelo compilador oferece:

  • Confiança de que todos os casos são tratados
  • Lembretes automáticos quando o ADT cresce
  • Menos MatchErrors em tempo de execução
  • Refatoração em larga escala mais segura

Reunindo tudo

Um ADT selado com cobertura completa. Adicionar uma nova variante acionaria aqui um aviso do compilador.

sealed trait Command
case object Start extends Command
case object Stop extends Command
case class SetSpeed(v: Int) extends Command
object Main {
  def run(c: Command): String = c match {
    case Start       => "starting"
    case Stop        => "stopping"
    case SetSpeed(v) => s"speed $v"
  }
  def main(args: Array[String]): Unit = {
    List(Start, SetSpeed(5), Stop).foreach(c => println(run(c)))
  }
}

Verificação rápida

Teste sua compreensão sobre correspondência exaustiva.

Recapitulação

Você aprendeu sobre correspondência exaustiva:

  • Uma correspondência é exaustiva quando cobre todas as variantes
  • Para traits selados, o compilador verifica isso e avisa sobre lacunas
  • Adicionar uma variante revela todas as correspondências incompletas
  • Evite case _ em ADTs selados para manter essa proteção
  • As guardas podem interromper a exaustividade; adicione um caso final sem guarda

Perguntas Frequentes

A aula “Correspondência exaustiva” é grátis?

Sim — o texto completo de “Correspondência exaustiva” é 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 “Correspondência exaustiva”?

Completude verificada pelo compilador. 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 “Correspondência exaustiva”?

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. Classes case
  2. Traits seladas
  3. Tipos de dados algébricos
  4. Correspondência exaustiva
← Voltar para Scala for Backend Engineering & Functional Programming