scala pattern matching
pattern matching是用来检查一个值是否满足一个模式的机制。一个成功的匹配也可以解析出一个值变成它的组成部分(constituent parts)。这是一个比Java switch语句功能更强大的版本,它也同样能用在一系列if/else语句的地方。
语义Syntax
一个match表达式有一个值,一个match关键字和至少一个case语句。
import scala.util.Random val x: Int = Random.nextInt(10) x match { case 0 => "zero" case 1 => "one" case 2 => "two" case _ => "many" }
上面的val x是一个0到10之间的随机数。x变成match的左操作数,在右边是一个有四个case的表达式。最后一个case _ 是一个”捕获所有“的case,对于任意的大于2的数字。Cases也被称作选项。
Match表达式是有值的。
def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many" } matchTest(3) // many matchTest(1) // one
这个match表达式有一个String类型,因为所有的case都返回String。因此,这个matchTest函数返回一个String。
匹配case class(Matching on case classes)
case class对于pattern matching特别有用。
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是一个抽象的超类,有三个具体的Notification类型,以case class Email,SMS和VoiceRecording来实现。现在我们可以在这些case class上进行pattern matching了。
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类型的参数,然后match Notification类型(举例来说:它找出这是否是一个Email、SMS或VoiceRecording)。在case Email(email, title, _),字段email和title在返回值时会使用,body被用_忽略了。
模式保护(Pattern guards)
pattern guard是简单的布尔表达式,用来让case更精确。只要在pattern后面加上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在重要人士列表中时才会匹配。
只匹配类型(matching on type only)
你也可以像这样匹配一个类型:
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类型的不同有不同的行为。这个在case需要在pattern上调用方法时很有用。这是一个约定:使用type的第一个字符作为case的标识符(这个case中的p和c)。
密封类(sealed classes)
trait和class可以被标记为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" }
这在pattern matching中很有有用,因为我们不需要catch all这个case。
注意
scala的pattern matching语句在通过case class来匹配代数类型时最有用。Scala也允许独立于case class的pattern定义,使用extractor objects的unapply方法(这里不太理解,需要看extractor object)。
相关推荐
在Scala众多强大的特性中,模式匹配(Pattern Matching)是一个非常引人注目的功能,它不仅仅局限于字符串匹配,而是广泛应用于数据结构的解析和组合。 #### 模式匹配的概念 通常当我们提到“模式匹配”时,往往会...
scala.util.matching - Pattern matching in text using regular expressions. scala.util.parsing.combinator - Composable combinators for parsing. scala.xml - XML parsing, manipulation, and serialization.
另外,该版本还对Pattern Matching进行了优化,使得在处理数据结构时更加灵活和高效。 在函数式编程方面,Scala 2.12.5提供了强大的函数库,包括集合API的增强。这个版本的集合库进一步提升了性能,并且添加了更多...
6. **Case类和Pattern Matching**:Scala的Case类和模式匹配功能使得处理枚举类型和解析数据变得更加方便。 7. **泛型**:Scala的泛型系统比Java的更为强大,可以更好地处理类型安全和类型擦除。 8. **对象和类的...
Working with higher-order functions and the powerful Scala collections library * Leveraging Scala's powerful pattern matching and case classes * Creating concurrent programs with Scala actors * ...
7. **Pattern Matching**:Scala 的模式匹配功能允许开发者以一种简洁的方式处理不同情况,常用于解构复合数据类型如案例类(case class)。 8. **Scalactic 和 ScalaTest**:虽然这两个不是 Scala SDK 的一部分,...
Pattern Matching** 模式匹配是Scala中的一个重要特性,可以用来解构复杂的数据结构,如列表、元组或自定义的case类,简化了条件判断和数据解析。 **8. Type Inference** Scala具有强大的类型推断能力,很多情况下...
书中可能会涵盖Scala的基础语法、函数式编程概念、类型系统,以及如何利用Scala的特性来优化Lift应用的性能,如使用case class和pattern matching等。 通过阅读这三本书,读者不仅可以掌握 Scala 语言的基本知识,...
Scala是一种强大的、现代的编程语言,它在IT领域中被广泛应用,特别是在大数据处理和分布式计算中...随着经验的积累,深入学习高级特性如 Actors、Pattern Matching 和 Type Classes,将有助于提升解决复杂问题的能力。
* Know how to use mixin composition with traits, pattern matching, concurrency with Actors, and other essential features, * Take advantage of Scala's built-in support for XML, * Learn how to develop ...
6. **Pattern Matching(模式匹配)**:Scala的模式匹配功能强大,不仅可以用于匹配简单的值,还能应用于类型匹配、抽象语法树等复杂场景。这种能力大大简化了代码的编写,提高了代码的可读性。 7. **Object ...
8. **Pattern Matching**: Scala的模式匹配功能允许开发者根据不同的情况执行不同的代码块,常用于解析数据和处理case类。 9. ** Higher-Kinded Types**: 这是Scala中的一个高级特性,允许定义类型参数为其他类型...
4. **Pattern Matching**:Scala的模式匹配允许开发者对数据进行解构,并根据不同的结构执行不同的代码块,这在处理数据结构和算法时非常有用。 5. **高阶函数**:Scala中的函数可以作为一等公民,可以赋值给变量、...
5. **模式匹配(Pattern Matching)**:Scala的强大的语法特性,允许解构复杂的数据结构并根据不同的形状执行不同操作。 6. **函数式数据结构**:如链表、树和图等,它们的操作都是通过纯函数完成,没有副作用。 7. ...
Scala的另一个重要特性是模式匹配(pattern matching),这是一个强大的工具,允许程序分支处理不同数据类型的结构和值。它类似于switch语句,但能处理更复杂的类型匹配。 了解Scala的这些基础知识对于深入学习...
- 进一步探索Scala的高级特性,如模式匹配(pattern matching)、隐式转换(implicit conversions)等。 - 深入理解Scala的类型系统,如何利用泛型(generics)编写灵活的代码。 - 开始接触Scala标准库中的常用类和方法...
四、模式匹配(Pattern Matching) 模式匹配是Scala中强大的语法特性,它允许我们在一个表达式中同时检查多种可能的情况。例如,解构元组或处理枚举类型时,模式匹配非常有用: ```scala val tuple = (1, "two") ...
Pattern matching is a powerful feature in Scala that allows for flexible data manipulation and conditional logic. - **Case Statements**: Case statements can be used to match values or patterns. For ...