Wyczerpujące dopasowywanie
Kompletność sprawdzana przez kompilator
Wyczerpujące dopasowywanie to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Czym jest wyczerpujące dopasowywanie?
Dopasowanie jest wyczerpujące, gdy obsługuje każdą możliwą wartość dopasowywanego typu.
W przypadku sealed trait kompilator zna wszystkie warianty i może sprawdzić, czy dopasowanie uwzględnia je wszystkie.
Kompletne dopasowanie
Gdy obsłużysz każdy wariant sealed trait, kompilator nie zgłosi zastrzeżeń i nie pojawi się żadne ostrzeżenie.
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))
}
}Kompilator czuwa
Jeśli pominiesz wariant, kompilator wyświetli podczas kompilacji ostrzeżenie non-exhaustive match.
To zabezpieczenie pozwala wykryć brak jeszcze przed uruchomieniem programu.
Późniejsze dodanie wariantu
Prawdziwa korzyść pojawia się po dodaniu nowego wariantu. Każde niekompletne dopasowanie w całej bazie kodu wyświetli ostrzeżenie, przypominając o obsłużeniu nowego przypadku.
Dzięki temu refaktoryzowanie jest bezpieczne i przewidywalne.
Dlaczego unikać wildcard?
Dodanie case _ => wycisza ostrzeżenia o niekompletnym dopasowaniu. Może to ukryć błędy, gdy później dodasz warianty.
W przypadku sealed ADT preferuj jawne wymienianie każdego wariantu, aby kompilator nadal zapewniał ochronę.
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))
}
}Kompletność wariantów z danymi
Kompletność dotyczy także wariantów zawierających dane. Przypisujesz pola do zmiennych, ale nadal musisz uwzględnić każdy wariant.
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)))
}
}Łączenie z guardami
Zachowaj ostrożność: guardy mogą sprawić, że dopasowanie będzie niekompletne, ponieważ kompilator nie może dowieść, że guardy obejmują wszystkie wartości.
Dodaj końcowy przypadek bez guarda dla tego samego wariantu, aby zachować kompletność.
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)))
}
}Kompletność z Option
Option z biblioteki standardowej to sealed ADT z Some i None. Dopasowanie do obu wariantów jest kompletne.
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))
}
}Zagnieżdżona kompletność
Kompletność pomaga także w przypadku zagnieżdżonych ADT. Kompilator analizuje każdy poziom rozpakowywanej struktury.
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))))
}
}Dlaczego to ma znaczenie
Sprawdzanie kompletności przez kompilator zapewnia:
- Pewność, że obsłużono każdy przypadek
- Automatyczne przypomnienia, gdy ADT się rozrasta
- Mniej błędów MatchError w czasie działania
- Bezpieczniejsze refaktoryzowanie na dużą skalę
Połączenie wszystkiego
Sealed ADT z pełnym pokryciem wariantów. Dodanie nowego wariantu wywołałoby tutaj ostrzeżenie kompilatora.
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)))
}
}Szybkie sprawdzenie
Sprawdź, jak rozumiesz wyczerpujące dopasowywanie.
Podsumowanie
Dowiedziałeś się o wyczerpującym dopasowywaniu:
- Dopasowanie jest wyczerpujące, gdy obejmuje każdy wariant
- W przypadku sealed traits kompilator to sprawdza i ostrzega o brakach
- Dodanie wariantu ujawnia każde niekompletne dopasowanie
- Unikaj
case _w sealed ADT, aby zachować tę ochronę - Guardy mogą naruszyć kompletność; dodaj przypadek końcowy bez guarda
Często zadawane pytania
Czy lekcja „Wyczerpujące dopasowywanie” jest bezpłatna?
Tak — pełny tekst „Wyczerpujące dopasowywanie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Wyczerpujące dopasowywanie”?
Kompletność sprawdzana przez kompilator Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Wyczerpujące dopasowywanie”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Klasy case
- Cechy sealed
- Algebraiczne typy danych
- Wyczerpujące dopasowywanie