Разница между сопоставлением с шаблоном Scala с использованием привязки переменных и защиты - PullRequest
0 голосов
/ 07 ноября 2018

При сопоставлении с образцом, какой будет сценарий, в котором будет необходимо связывание переменных, где защита будет недостаточной?

  "hello" match {
    case greeting @ ("yo" | "hello" | "hola") => println(s"greeting is $greeting")
    case _                                    => println("some other greeting")
  }

  "hello" match {
    case greeting if (greeting == "yo" || greeting == "hello" || greeting == "hola") => println(s"greeting is $greeting")
    case _ => println("some other greeting")
  }

Кажется, что оба эти подхода решают одну и ту же проблему.

1 Ответ

0 голосов
/ 08 ноября 2018

При сопоставлении на запечатанных чертах, есть огромная разница

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)
...