模式匹配
scala中有一个非常强大的模式匹配机制,可以应用在很多场景:
- switch语句
- 类型查询
- 使用模式匹配快速获取数据
简单模式匹配
在Java中,有switch关键字,可以简化if条件判断语句。在scala中,可以使用match表达式替代。
语法格式
变量 match {
case "常量1" => 表达式1
case "常量2" => 表达式2
case "常量3" => 表达式3
case _ => 表达式4 // 默认匹配
}
代码示例
import scala.io.StdIn
object Test01 {
def main(args: Array[String]): Unit = {
println("请输入一个词:")
//从控制台读取一行文本
val name: String = StdIn.readLine()
//输出
val result = name match {
case "hadoop" => "大数据分布式存储和计算框架"
case "zookeeper" => "大数据分布式协调服务框架"
case "spark" => "大数据分布式内存计算框架"
case _ => "未匹配"
}
//输出
println(s"result = ${result}")
}
}
效果截图
匹配类型
除了像Java中的switch匹配数据之外,match表达式还可以进行类型匹配。如果我们要根据不同的数据类型,来执行不同的逻辑,也可以使用match表达式来实现。
语法格式
变量 match {
case 类型1变量名: 类型1 => 表达式1
case 类型2变量名: 类型2 => 表达式2
case 类型3变量名: 类型3 => 表达式3
...
case _ => 表达式4
}
代码示例
如果case表达式中无需使用到匹配到的变量,可以使用下划线代代替
object Test02 {
def main(args: Array[String]): Unit = {
//定义一个Any 类型的变量
val b:Any = "hadoop"
//使用case 判断类型
val r = b match {
case _:String => "String"
case _:Int => "Int"
case _:Double => "Double"
}
println(r) //String
}
}
匹配样例类
scala可以使用模式匹配来匹配样例类,从而可以快速获取样例类中的成员数据
代码示例
object Test03 {
//创建两个样例类 Customer 和 order
// Customer包含姓名、年龄字段
case class Person(name: String, age: Int)
// Order包含id字段
case class Order(id: String)
def main(args: Array[String]): Unit = {
//创建样例类对象,并赋值为Any类型
val customer: Any = Person("张三", 20)
val order: Any = Order("001")
//使用match...case 表达式来进行模式匹配
customer match {
case Person(name, age) => println(s"name = ${name} age = ${age}")
case Order(id) => println(s"id = ${id}")
case _ => println("未匹配")
}
order match {
case Person(name, age) => println(s"name = ${name} age = ${age}")
case Order(id) => println(s"id = ${id}")
case _ => println("未匹配")
}
}
}
守卫
在Java中,只能简单地添加多个case标签,在scala中,可以使用守卫来简化上述代码——也就是在case语句中添加if条件判断。
代码示例
import scala.io.StdIn
object Test04 {
def main(args: Array[String]): Unit = {
//从控制台读入一个数字a
val a = StdIn.readInt()
//使用case 进行匹配
a match {
//如果 a >= 0 而且 a <= 3,打印[0-3]
case _ if a >= 0 && a <= 3 => println("[0-3]")
//如果 a >= 4 而且 a <= 8,打印[4,8]
case _ if a >= 4 && a <= 8 => println("[4-8]")
//其它情况输出未匹配
case _ => println("未匹配")
}
}
}
匹配数组
代码示例
object Test05 {
def main(args: Array[String]): Unit = {
//定义一个数组
val array = Array(1, 3, 5)
array match {
// 以1开头,后续的两个元素不固定 名字可以任意起
case Array(1, a, b) => println(a + "\t" + b)
//只匹配一个0元素 的数组
case Array(0) => println("0")
//可以任意数量,但是以0开头
case Array(0, _*) => println("匹配以0开头的数组")
case _ => println("未匹配成功")
}
}
}
匹配列表
代码示例
object Test06 {
def main(args: Array[String]): Unit = {
//定义一个列表
val list = List(0,1, 3)
// list match {
// // 以0开头,后续的两个元素不固定 名字可以任意起
// case List(0, a, b) => println(a + "\t" + b)
// //只匹配一个0元素 的列表
// case List(0) => println("0")
// //可以任意数量,但是以0开头
// case List(0, _*) => println("匹配以0开头的列表")
// case _ => println("未匹配成功")
// }
list match {
case 0 :: Nil => println("只有0的列表")
case 0 :: tail => println("0开头的列表")
case x :: y :: Nil => println(s"只有另两个元素${x}, ${y}的列表")
case _ => println("未匹配")
}
}
}
匹配元组
代码示例
object Test07 {
def main(args: Array[String]): Unit = {
val a = (1, "hadoop", 1.0)
a match {
case (1, x, y) => println(s"三个元素,1开头的元组:1,${x},${y}")
case (x, y, 1.0) => println(s"三个元素,1.0结尾的元组:${x}, ${y}, 1.0")
case _ => println("未匹配")
}
}
}
变量声明中的模式匹配
在定义变量的时候,可以使用模式匹配快速获取数据
代码示例
def main(args: Array[String]): Unit = {
//获取数组中的元素
//生成包含0-10数字的数组
val array: Array[Int] = (0 to 10).toArray
//使用模式匹配分别获取第二个、第三个、第四个元素
val Array(_, x, y, z, _*) = array
println(x,y,z)
//获取List中的数据
val list = (1 to 10).toList
// val a :: b :: tail = list
val List(a,b,_*) = list
println(a, b)
}