在进行模式匹配时,在什么情况下需要变量绑定,而防护就不够?
"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")
}
这两种方法似乎都可以解决相同的问题。
答案 0 :(得分:0)
匹配密封性状时,存在巨大差异
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)