在Scala中不存在Switch语句,但这里存在比Switch更强大的Case
匹配值相等
import scala.util.Random
val x: Int = Random.nextInt(10)
x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "many"
}
_
是可选的。类似于 Switch 中的 default。当上方的场景都没有相应的匹配项的时候,就执行该语句。
match case
其执行顺序是从上往下执行,直到找到匹配项之后,执行完全,退出。
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
matchTest(3) // many
matchTest(1) // one
可以像if语句那样结果赋值给变量或者构成方法。
abstract class Notification
case class Email(sender: String, title: String, body: String) extends Notification
case class SMS(caller: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification
def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
s"You got an email from $email with title: $title"
case SMS(number, message) =>
s"You got an SMS from $number! Message: $message"
case VoiceRecording(name, link) =>
s"you received a Voice Recording from $name! Click the link to hear it: $link"
}
}
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
println(showNotification(someSms)) // prints You got an SMS from 12345! Message: Are you there?
println(showNotification(someVoiceRecording)) // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123
匹配Class类型,这里Email、SMS、VoiceRecording都继承于Notification,当case匹配到对象实例相匹配的类型时,就执行与之相匹配的代码,同时会将构造参数进行填充。
还可以在类匹配之后,还可以使用boolean表达式
def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = {
notification match {
case Email(email, _, _) if importantPeopleInfo.contains(email) =>
"You got an email from special someone!"
case SMS(number, _) if importantPeopleInfo.contains(number) =>
"You got an SMS from special someone!"
case other =>
showNotification(other) // nothing special, delegate to our original showNotification function
}
}
val importantPeopleInfo = Seq("867-5309", "jenny@gmail.com")
val someSms = SMS("867-5309", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
val importantEmail = Email("jenny@gmail.com", "Drinks tonight?", "I'm free after 5!")
val importantSms = SMS("867-5309", "I'm here! Where are you?")
println(showImportantNotification(someSms, importantPeopleInfo))
println(showImportantNotification(someVoiceRecording, importantPeopleInfo))
println(showImportantNotification(importantEmail, importantPeopleInfo))
println(showImportantNotification(importantSms, importantPeopleInfo))
类型匹配
abstract class Device
case class Phone(model: String) extends Device{
def screenOff = "Turning screen off"
}
case class Computer(model: String) extends Device {
def screenSaverOn = "Turning screen saver on..."
}
def goIdle(device: Device) = device match {
case p: Phone => p.screenOff
case c: Computer => c.screenSaverOn
}
被Sealed标记的类
sealed abstract class Furniture
case class Couch() extends Furniture
case class Chair() extends Furniture
def findPlaceToSit(piece: Furniture): String = piece match {
case a: Couch => "Lie on the couch"
case b: Chair => "Sit on the chair"
}
sealed 关键字主要有2个作用:
- 其修饰的trait,class只能在当前文件里面被继承;
- 在检查模式匹配的时候,用sealed修饰目的是让scala知道这些case的所有情况,scala就能够在编译的时候进行检查,看你写的代码是否有没有漏掉什么没case到,减少编程的错误。