【Scala之旅】样例类与模式匹配
样例类样例类就像普通的类一样,但有一些关键的区别,我们将会在下面对它们进行讨论。样例类对建模不可变数据很有帮助。在接下来的步骤中,我们将会看到它们在模式匹配中的重要作用。 定义样例类一个最小的样例类需要关键字 case class Book(isbn: String) val frankenstein = Book("978-0486282114") 注意,不需要用关键字 当您创建带有参数的样例类时,参数是公共的 case class Message(sender: String,recipient: String,body: String) val message1 = Message("guillaume@quebec.ca","jorge@catalonia.es","?a va ?") println(message1.sender) // prints guillaume@quebec.ca message1.sender = "travis@washington.us" // this line does not compile 你不能重新指定 比较用结构来比较样例类,而不是引用: case class Message(sender: String,body: String) val message2 = Message("jorge@catalonia.es","guillaume@quebec.ca","Com va?") val message3 = Message("jorge@catalonia.es","Com va?") val messagesAreTheSame = message2 == message3 // true 尽管 复制你可以通过使用 case class Message(sender: String,body: String) val message4 = Message("julien@bretagne.fr","travis@washington.us","Me zo o komz gant ma amezeg") val message5 = message4.copy(sender = message4.recipient,recipient = "claire@bourgogne.fr") message5.sender // travis@washington.us message5.recipient // claire@bourgogne.fr message5.body // "Me zo o komz gant ma amezeg"
模式匹配模式匹配是一种根据模式检查值的机制。一个成功的匹配也可以将一个值分解为它的组成部分。它是Java中 语法一个匹配表达式有一个值、关键字 import scala.util.Random val x: Int = Random.nextInt(10) x match { case 0 => "zero" case 1 => "one" case 2 => "two" case _ => "many" } 上面的 匹配表达式有一个值。 def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many" } matchTest(3) // many matchTest(1) // one 这个匹配表达式有一个字符串类型,因为所有的样例都返回字符串。因此,函数 匹配样例类样例类对于模式匹配特别有用。 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 函数 模式守卫模式守卫只是简单的布尔表达式,用于使情况更具体。只要在模式之后添加 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","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 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" } 这对于模式匹配非常有用,因为我们不需要“捕获所有”的 case。 注意事项Scala的模式匹配语句对于通过case类表示的代数类型的匹配非常有用。Scala还允许独立于case类的模式定义,在提取器对象中使用 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |