网站建设与管理工作内容百度搜索网站排名
Scala中有一个非常强大的模式匹配机制,应用也非常广泛, 例如:
-
判断固定值
-
类型查询
-
快速获取数据
简单模式匹配
一个模式匹配包含了一系列备选项,每个备选项都开始于关键字 case。且每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
格式:
变量 match {case "常量 1 " => 表达式 1case "常量 2 " => 表达式 2case "常量 3 " => 表达式 3case _ => 表达式 4 // 默认匹配项}
执行流程
-
先执行第一个case, 看变量值和该case对应的常量值是否一致.
-
如果一致, 则执行该case对应的表达式.
-
如果不一致, 则往后执行下一个case, 看变量值和该case对应的常量值是否一致.
-
以此类推, 如果所有的case都不匹配, 则执行case _对应的表达式.
需求:
-
提示用户录入一个单词并接收.
-
判断该单词是否能够匹配以下单词,如果能匹配,返回一句话
-
打印结果.
代码示例:
package test11import scala.io.StdInobject Test2 {def main(args: Array[String]): Unit = {println("请输入一个字符串")val str = StdIn.readLine()val result = str match {case "hadoop" => "大数据分布式存储和计算框架"case "zookeeper" => "大数据分布式协调服务框架"case "spark" => "大数据分布式内存计算框架"case _ => "未匹配"}println(result)//简写形式val result2 = str match {case "hadoop" => println("大数据分布式存储和计算框架")case "zookeeper" => println("大数据分布式协调服务框架")case "spark" => println("大数据分布式内存计算框架")case _ => println("未匹配")}}}
匹配类型
除了匹配数据之外, match表达式还可以进行类型匹配。如果我们要根据不同的数据类型,来执行不同的逻辑,也可以使用match表达式来实现。
格式:
对象名 match {case 变量名 1 : 类型 1 => 表达式 1case 变量名 2 : 类型 2 => 表达式 2case 变量名 3 : 类型 3 => 表达式 3...case _ => 表达式 4
}
需求
-
定义一个变量为Any类型,然后分别给其赋值为"hadoop"、 1 、1.0
-
定义模式匹配,然后分别打印类型的名称
代码示例:
package test11object Test3 {def main(args: Array[String]): Unit = {// val a: Any = 1.0// val a: Any = "hello"val a: Any = 1val result = a match {case x: String => s"$x 是String类型的数据"case x: Double => s"$x 是Double类型的数据"case x: Int => s"$x 是Int类型的数据"case _ => "未匹配"}println(result)// 4. 优化版, 如果在case校验的时候, 变量没有被使用, 则可以用_替代.val result1 = a match {case _: String => "String"case _: Int => "Int"case _: Double => "Double"case _ => "未匹配"}println(result1)}
}
守卫
所谓的守卫指的是在case语句中添加if条件判断, 这样可以让我们的代码更简洁, 更优雅.
格式
变量 match {case 变量名 if条件 1 => 表达式 1case 变量名 if条件 2 => 表达式 2case 变量名 if条件 3 => 表达式 3...case _ => 表达式 4}
需求
-
从控制台读入一个数字a(使用StdIn.readInt)
-
如果 a >= 0 而且 a <= 3,打印[0-3]
-
如果 a >= 4 而且 a <= 8,打印[4,8]
-
否则,打印未匹配
package test11import scala.io.StdInobject Test4 {def main(args: Array[String]): Unit = {println("请输入一个整数:")val num = StdIn.readInt()num match {case a if a >= 0 && a <= 3 => println("[0 - 3]")case a if a >= 4 && a <= 8 => println("[4 - 8]")case _ => println("不匹配")}}
}
匹配样例类
Scala中可以使用模式匹配来匹配样例类,从而实现可以快速获取样例类中的成员数据。后续,我们在开发Akka案例时,还会经常用到。
格式
对象名 match {case 样例类型 1 (字段 1 , 字段 2 , 字段n) => 表达式 1case 样例类型 2 (字段 1 , 字段 2 , 字段n) => 表达式 2case 样例类型 3 (字段 1 , 字段 2 , 字段n) => 表达式 3...case _ => 表达式 4}
注意:
-
样例类型后的小括号中, 编写的字段个数要和该样例类的字段个数保持一致.
-
通过match进行模式匹配的时候, 要匹配的对象必须声明为: Any类型.
需求
-
创建两个样例类Customer(包含姓名, 年龄字段), Order(包含id字段)
-
分别定义两个样例类的对象,并指定为Any类型
-
使用模式匹配这两个对象,并分别打印它们的成员变量值
代码示例:
package test11object Test5 {case class Customer(var name: String, var age: Int)case class Order(id: Int)def main(args: Array[String]): Unit = {val c: Any = Customer("Tom", 23)val o: Any = Order(123)val arr: Any = Array(0, 1)c match {case Customer(a, b) => println(s"Customer类型的对象,name=$a,age=$b")case Order(c) => println(s"Order类型,id=$c")case _ => println("未匹配")}o match {case Customer(a, b) => println(s"Customer类型的对象,name=$a,age=$b")case Order(c) => println(s"Order类型,id=$c")case _ => println("未匹配")}arr match {case Customer(a, b) => println(s"Customer类型的对象,name=$a,age=$b")case Order(c) => println(s"Order类型,id=$c")case _ => println("未匹配")}}
}
匹配集合
除了上述功能之外, Scala中的模式匹配,还能用来匹配数组, 元组, 集合(列表, 集, 映射)等。
匹配数组
package test11object Test6 {def main(args: Array[String]): Unit = {val arr1 = Array(1, 2, 3)val arr2 = Array(0)val arr3 = Array(1, 2, 4, 5, 6, 7)arr1 match {case Array(1, x, y) => println(s"匹配长度为 3 , 首元素为 1 , 后两个元素是: $x, $y")case Array(0) => println("匹配只有一个0元素的数组")case Array(1, _*) => println("匹配:第一个元素是1,后边的元素随意")case _ => println("未匹配")}arr2 match {case Array(1, x, y) => println(s"匹配长度为 3 , 首元素为 1 , 后两个元素是: $x, $y")case Array(0) => println("匹配只有一个0元素的数组")case Array(1, _*) => println("匹配:第一个元素是1,后边的元素随意")case _ => println("未匹配")}arr3 match {case Array(1, x, y) => println(s"匹配长度为 3 , 首元素为 1 , 后两个元素是: $x, $y")case Array(0) => println("匹配只有一个0元素的数组")case Array(1, _*) => println("匹配:第一个元素是1,后边的元素随意")case _ => println("未匹配")}}
}
匹配列表
package test11object Test7 {def main(args: Array[String]): Unit = {val list1 = List(0)val list2 = List(0, 1, 2, 3, 4, 5)val list3 = List(1, 2)list1 match {case List(0) => println("匹配: 只有一个0元素的列表")case List(0, _*) => println("匹配: 0开头,后边元素无所谓的列表")case List(x, y) => println(s"匹配:只有俩个元素的列表,元素为:$x,$y")case _ => println("未匹配")}//思路二: 采用关键字优化 Nil, taillist1 match {case 0 :: Nil => println("匹配: 只有一个 0 元素的列表")case 0 :: tail => println("匹配: 0 开头, 后边元素无所谓的列表")case x :: y :: Nil => println(s"匹配: 只有两个元素的列表, 元素为: $x, $y")case _ => println("未匹配")}list2 match {case List(0) => println("匹配: 只有一个0元素的列表")case List(0, _*) => println("匹配: 0开头,后边元素无所谓的列表")case List(x, y) => println(s"匹配:只有俩个元素的列表,元素为:$x,$y")case _ => println("未匹配")}list3 match {case List(0) => println("匹配: 只有一个0元素的列表")case List(0, _*) => println("匹配: 0开头,后边元素无所谓的列表")case List(x, y) => println(s"匹配:只有俩个元素的列表,元素为:$x,$y")case _ => println("未匹配")}}
}
匹配元组
package test11object Test8 {def main(args: Array[String]): Unit = {val a = (1, 2, 3)val b = (3, 4, 5)val c = (3, 4)a match {case (1, x, y) => println(s"匹配:长度为3,以1开头,后面俩个元素随意的元组,这里的后俩个元素是:$x,$y")case (x, y, 5) => println(s"匹配:长度为3,以5结尾,前边俩个元素随意的元组,这里的前俩个元素是:$x,$y")case _ => println("未匹配")}}
}
变量声明中的模式匹配
在定义变量时,可以使用模式匹配快速获取数据. 例如: 快速从数组,列表中获取数据.
package test11object Test9 {def main(args: Array[String]): Unit = {val arr = (0 to 10).toArray//使用模式匹配分别获取第二个、第三个、第四个元素val Array(_, x, y, z, _*) = arrprintln(x, y, z)val list = (0 to 10).toList// 使用模式匹配分别获取第一个、第二个元素val List(a, b, _*) = list// 使用模式匹配分别获取第一个、第二个元素val c :: d :: tail = listprintln(a, b)println(c, d)}}
匹配for表达式
Scala中还可以使用模式匹配来匹配for表达式,从而实现快速获取指定数据, 让我们的代码看起来更简洁, 更优雅.
需求
-
定义变量记录学生的姓名和年龄, 例如: "张三" -> 23, "李四" -> 24, "王五" -> 23, "赵六" -> 26
-
获取所有年龄为 23 的学生信息, 并打印结果.
package test11object Test10 {def main(args: Array[String]): Unit = {val map1 = Map("张三" -> 23, "李四" -> 24, "王五" -> 23, "赵六" -> 26)for ((k, v) <- map1 if v == 23) println(s"$k = $v")println("-" * 15)for ((k, 23) <- map1) println(k + " = 23")}
}