1、模式匹配

模式匹配是一种根据模式检查值的机制。它是switch(Java中语句)的更强大版本,它同样可以用来代替一系列if / else语句。

  • 句法

匹配表达式具有值,match关键字和至少一个case子句。

import scala.util.Random

val x: Int = Random.nextInt(10)

x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "other"
}

  val x上面是0和10之间的随机整数,x成为的左操作数match运算符和右边是与4箱子的表达式。最后一种情况(_)是任何其他可能Int值的“全部捕获”情况。案件也被称为替代品

  • 匹配案例类

案例类对模式匹配特别有用。

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

  Notification是具有与壳体的类实现的三个具体的通知类型的抽象超类EmailSMSVoiceRecording。现在我们可以对这些案例类进行模式匹配:

def showNotification(notification: Notification): String = {
notification match {
case Email(sender, title, _) =>
s"You got an email from $sender 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(someSmps)) println(showNotification(someVoiceRecording))

  该函数showNotification作为参数的抽象类型Notification和类型相匹配Notification(即,它计算出它是否是一个EmailSMSVoiceRecording)。在case Email(sender, title, _)字段中sender并且title在返回值中使用但是body忽略该字段_

  • 模式守护

模式保护只是布尔表达式,用于使案例更具体。只需if <boolean expression>在模式后添加。

def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = {
notification match {
case Email(sender, _, _) if importantPeopleInfo.contains(sender) =>
"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)
}
} 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))

  在图中case Email(sender, _, _) if importantPeopleInfo.contains(sender),只有sender在重要人物列表中才匹配模式。

  • 仅在类型上匹配
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
}

  def goIdle具有不同的行为取决于类型Device。当案例需要在模式上调用方法时,这很有用。它是使用类型的情况下标识(第一个字母的公约pc在这种情况下)。

  • 密封课程

可以标记特征和类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"
}

  

2、案例类

  • 定义案例类

最小的案例类需要关键字case class,标识符和参数列表(可能为空):

case class Book(isbn: String)

val frankenstein = Book("912-0111182114")

  注意:实例化Book案例时没有new关键字。这是因为case类apply默认有一个方法来处理对象构造。

使用参数创建案例类时,参数是公共val的。

case class Message(sender: String, recipient: String, body: String)
val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "Ça va ?") println(message1.sender) //合法的
message1.sender = "travis@washington.us" // 不合法的

  不能重新分配,message1.sender因为它是一个val(即不可变的)。

最新文章

  1. MYSQL 基本SQL语句
  2. bat转exe工具 Bat To Exe Converter v2.4.7 绿色版
  3. angular服务一
  4. python基础之day2
  5. WCF服务寄宿应用程序
  6. Verilog学习笔记简单功能实现(三)...............同步有限状态机
  7. ubuntu 重置密码
  8. 冒泡排序(C++版)
  9. #pragma——push and pop
  10. 玩转CSLA.NET小技巧系列一:跳转页面丢失session,如何解决
  11. 用arm-linux-gcc v4.3.4交叉编译Qt4.8.3
  12. 【HDOJ】 七百题留念
  13. Java基础——深入理解Java中的final关键字(转载)
  14. Linux的kobject机制
  15. 关于oracle数据库备份还原-impdp,expdp
  16. 【javascript】继承
  17. Keras + LSTM 做回归demo 2
  18. ECMA6 New Features
  19. ubuntu16.04 install qtcreator
  20. ssh命令详解

热门文章

  1. 【机器学习】【条件随机场CRF-3】条件随机场的参数化形式详解 + 画出对应的状态路径图 + 给出对应的矩阵表示
  2. 【Learning Notes】线性链条件随机场(CRF)原理及实现
  3. Python--day48--今日内容
  4. jstack简介
  5. 机器学习——集成学习之Boosting
  6. 2018-2-13-C#-解析-sln-文件
  7. url查找参数
  8. Linux 内核 动态设备
  9. Linux 内核总线注册
  10. Oracle Net Manager 的使用方法(监听的配置方法)