При сопоставлении на запечатанных чертах, есть огромная разница
sealed trait Option[+A]
case class Some[A](get: A) extends Option[A]
case object None extends Option[Nothing]
val x: Option[String] = ???
С сопоставлением с шаблоном это приятно и читабельно:
x match {
case Some(string) => println("got " + string)
case None => println("didn't get anything")
}
А также компилятор выдаст предупреждение, если вы пропустите случай:
x match {
case Some(string) => println("got " + string)
} // gives you warning that match might fail on None
Для сторожевой версии вам нужно использовать приведение, и для забытых случаев предупреждений нет:
x match {
case some if some.isInstanceOf[Some[_]] =>
println("got " + some.asInstanceOf[Some[String]].get)
case none if some == None =>
println("didn't get anything")
}
Кроме того, охранники быстро становятся ужасными, когда хотят проверить структуру глубже, чем на один уровень. Сравните:
case Some(Some(string)) => println(string)
с
case s if s.isInstanceOf[Some[_]] && s.asInstanceOf[Some[_]].get.isInstanceOf[Some[_]] =>
println(s.asInstanceOf[Some[_]].get.asInstanceOf[Some[String]].get)