模式匹配是C或java中switch语句的泛化,match方法用于代替switch语句。它定义在Scala根类Any上,因此所有对象都可用。match方法包括一组case作为参数,每个表示一种模式,并且如果匹配可以执行一个或多个表达式。=>符号用于分割模式和表达式。本文通过实例说明模式匹配和case类的使用。
模式匹配
模式匹配是C或java中switch语句的泛化,match方法用于代替switch语句。它定义在Scala根类Any上,因此所有对象都可用。match方法包括一组case作为参数,每个表示一种模式,并且如果匹配可以执行一个或多个表达式。=>符号用于分割模式和表达式。
模式匹配可以用于方法,集合遍历中:
object Main {
def main(args: Array[String]) {
println(matchValue(2))
}
def matchValue(i: Int): String = i match {
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => "unknown"
}
}
输出结果为two;如果匹配不同case返回不同类型,则使用Any,而不使用String和Int具体类型。这里_
表示其他情况。
Case类
通过在class前增加关键字case定义case类,它用于与case表达式进行模式匹配。case有下列优势:
- 编译器自动改变构造函数参数为不可变字段
- 编译器自动给case类增加equals、hashCode、toString方法
- 实例化对象不需要使用new关键字
语法如下:
case class Calculator(Value: Type)
举例:
object Main {
case class Employee(id: Int, employee_name: String) // case class
def main(args: Array[String]): Unit = {
val a = Employee(1, "abc1")
val b = Employee(2, "abc2")
val c = Employee(3, "abc3")
for (emp <- List(a, b, c)) {
emp match {
case Employee(1, "abc1") => println("Hello abc")
case Employee(2, "abc2") => println("Hello xyz")
case Employee(id, employee_name) => println("ID: " + id + ", Employee:" + employee_name)
}
}
}
}
首先定义Employee类,通过case关键字标识,因此能够使用模式匹配,内部使用equals、hashCode方法进行比较;实例化case类不需要new关键字。
输出结果:
Hello abc
Hello xyz
ID: 3, Employee:abc3
再看一个示例,case后面的表达式可以写多个:
object Main {
case class Person(firstName: String, lastName: String,age: Int, emailId:String)
def main(args: Array[String]): Unit ={
val Tim = Person("Tim","Cole",25,"tim.cole@fp.com")
val Jane = Person("Jane","Doe",21,"jane.doe@fp.com")
def checkAge(p: Person):Any = p match{
case Person(_,"Doe",_,_) => if (p.age > 20)
println(s"${p.firstName} Doe's Age is greater than 20")
case _ => println("Unknown Last Name")
}
//Prints - Jane Doe's Age is greater than 20
checkAge(Jane)
//Prints - Unknown Last Name
checkAge(Tim)
}
}
case条件匹配后面的Person,仅提供关心的参数,其他使用参数_
代替。
输出结果:
Jane Doe's Age is greater than 20
Unknown Last Name