Scala模式匹配
来源:互联网 发布:淘宝banner尺寸大小 编辑:程序博客网 时间:2024/05/21 17:56
- 语法
- Case类匹配
- 模式守护
- 只匹配类型
- 密封类
- Notes
模式匹配是根据模式检查值的机制。一个成功的匹配可以将值分解成其组成部分。它Java switch
语句的一个更强大的版本,也可用于替代一系列if/else语句。
语法
一个匹配表达式有一个值,match
关键字和至少一个case
语句。
import scala.util.Randomval x: Int = Random.nextInt(10)x match { case 0 => "zero" case 1 => "one" case 2 => "two" case _ => "many"}
上面的val x
是一个在0到10之间的随机整数。x
是match
操作符的左操作数,右边是包含4个cases的表达式。最后一个case _
是一个”catch all”,代表了任意大于2的数字。Cases可被称为选择。
匹配表达式有一个值。
def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many"}matchTest(3) // manymatchTest(1) // one
这是一个字符串匹配表达式,所有的cases都返回字符串,因此,matchTest
函数返回一个字符串。
Case类匹配
Case类对于模式匹配特别有用。
abstract class Notificationcase class Email(sender: String, title: String, body: String) extends Notificationcase class SMS(caller: String, message: String) extends Notificationcase class VoiceRecording(contactName: String, link: String) extends Notification
Notification
是一个抽象父类,有三个具体的Notification类型,分别是Email
,SMS
和VoiceRecording
。现在可以对这些Case类进行模式匹配。
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
showNotification
函数有一个Notification
类型的参数,内部对Notification
类型进行了匹配(分别匹配Email
,SMS
和VoiceRecording
)。在case Email(email, title, _)
中字段email
和title
用于返回值,但是body
使用_
进行了忽略。
模式守护
模式守护是简单的布尔表达式,用于让情况更加具体。只要在模式后面添加if <boolean expression>
。
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))
在case Email(email, _, _) if importantPeopleInfo.contains(email)
中,只有email
在important people列表中才能匹配模式。
只匹配类型
可以按照如下方式匹配类型:
abstract class Devicecase 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
类型不同有不同的行为。当case需要调用模式的方法时非常有用。习惯使用类型的第一个字符作为case的标识符(这个例子中是p
和c
)。
密封类
特征和类可以标记为sealed
,意思是所有子类型都必须在同一个文件中声明。确保所有子类型是已知的。
sealed abstract class Furniturecase class Couch() extends Furniturecase class Chair() extends Furnituredef findPlaceToSit(piece: Furniture): String = piece match { case a: Couch => "Lie on the couch" case b: Chair => "Sit on the chair"}
因为我们不需要”catch all” case,所以这对模式匹配非常有用。
Notes
Scala的模式匹配语句对于通过Case类表达的代数类型匹配非常有用。Scala也允许Case类独立定义模式,在extractor objects中使用unapply
方法。
- scala 正则匹配(模式匹配)
- scala简要:模式匹配
- Scala模式匹配
- Scala 模式匹配
- Scala中的模式匹配
- scala 模式匹配
- Scala之模式匹配
- Scala的模式匹配
- Scala模式匹配
- scala的模式匹配
- Scala 之 模式匹配
- Scala之模式匹配
- scala模式匹配·
- Scala模式匹配
- Scala模式匹配
- scala模式匹配
- scala基础-模式匹配
- Scala模式匹配
- 影如人生
- 算法-快速排序(为什么每次都要从右边开始)
- golang日記ーsprint有什么用? 和+号的区别
- 文章标题
- 用bat命令重启explorer的方法
- Scala模式匹配
- MyFlag Step2:APP雏形的展现以及相关规范
- 因子分析、主成分分析(PCA)、独立成分分析(ICA)——斯坦福CS229机器学习个人总结(六)
- LeetCode (Merge Intervals)
- Java泛型_嵌套_其它
- 面试总结(4):top、left、right、bottom 和 translationX、translationY 和 scrollX,scrollY的区别
- 成功的人在多于2个方面都做的好
- mybatis与spring整合
- Android 备忘录 -- Intent