Scalascala模式匹配

文章目录

  • 模式匹配
    • 简单模式匹配
    • 匹配类型
    • 守卫
    • 匹配样例类
    • 匹配集合
      • 匹配数组
      • 匹配列表
      • 匹配元组
    • 变量声明中的模式匹配
      • 示例 | 获取数组中的元素
      • 示例 | 获取List中的数据

模式匹配

scala中有一个非常强大的模式匹配机制,可以应用在很多场景:

  • 1.switch语句
  • 2.类型查询
  • 3.使用模式匹配快速获取数据

简单模式匹配

在Java中,有switch关键字,可以简化if条件判断语句。在scala中,可以使用match表达式替代。

语法格式

变量 match {case "常量1" => 表达式1case "常量2" => 表达式2case "常量3" => 表达式3case _ => 表达式4		// 默认匹配
}

示例

  • 1.从控制台输入一个单词(使用StdIn.readLine方法)
  • 2.判断该单词是否能够匹配以下单词,如果能匹配,返回一句话
  • 3.打印这句话
单词返回
hadoop大数据分布式存储和计算框架
zookeeper大数据分布式协调服务框架
spark大数据分布式内存计算框架
未匹配未匹配

参考代码

println("请输出一个词:")
// StdIn.readLine表示从控制台读取一行文本
val name = StdIn.readLine()val result = name match {case "hadoop" => "大数据分布式存储和计算框架"case "zookeeper" => "大数据分布式协调服务框架"case "spark" => "大数据分布式内存计算框架"case _ => "未匹配"
}
println(result)

匹配类型

除了像Java中的switch匹配数据之外,match表达式还可以进行类型匹配。如果我们要根据不同的数据类型,来执行不同的逻辑,也可以使用match表达式来实现。

语法格式

变量 match {case 类型1的变量名: 类型1 => 表达式1case 类型2的变量名: 类型2 => 表达式2case 类型3的变量名: 类型3 => 表达式3...case _ => 表达式4
}

示例

  • 定义一个变量为Any类型,然后分别给其赋值为"hadoop"、1、1.0
  • 定义模式匹配,然后分别打印类型的名称

参考代码

val a:Any = "hadoop"
​
val result = a match {case _:String => "String"case _:Int => "Int"case _:Double => "Double"
}
println(result)

如果case表达式中无需使用到匹配到的变量,可以使用下划线代代替

守卫

在Java中,只能简单地添加多个case标签,例如:要匹配0-7,就需要写出来8个case语句。例如:

int a = 0;
switch(a) {case 0: a += 1;case 1: a += 1;case 2: a += 1;case 3: a += 1;case 4: a += 2;case 5: a += 2;case 6: a += 2;case 7: a += 2;default: a = 0;
}

在scala中,可以使用守卫来简化上述代码——也就是在case语句中添加if条件判断。

示例

  • 从控制台读入一个数字a(使用StdIn.readInt)
  • 如果 a >= 0 而且 a <= 3,打印[0-3]
  • 如果 a >= 4 而且 a <= 8,打印[3,8]
  • 否则,打印未匹配

参考代码

val a = StdIn.readInt()
a match {case _ if a >= 0 && a <= 3 => println("[0-3]")case _ if a >= 4 && a <= 8 => println("[3-8]")case _ => println("未匹配")
}

匹配样例类

scala可以使用模式匹配来匹配样例类,从而可以快速获取样例类中的成员数据。后续,我们在开发Akka案例时,还会用到。

示例

  • 创建两个样例类Customer、Order
    Customer包含姓名、年龄字段
    Order包含id字段
  • 分别定义两个样例类的对象,并指定为Any类型
  • 使用模式匹配这两个对象,并分别打印它们的成员变量值

参考代码

// 1. 创建两个样例类
case class Person(name:String, age:Int)
case class Order(id:String)def main(args: Array[String]): Unit = {// 2. 创建样例类对象,并赋值为Any类型val zhangsan:Any = Person("张三", 20)val order1:Any = Order("001")// 3. 使用match...case表达式来进行模式匹配// 获取样例类中成员变量order1 match {case Person(name, age) => println(s"姓名:${name} 年龄:${age}")case Order(id) => println(s"ID为:${id1}")case _ => println("未匹配")}
}

匹配集合

scala中的模式匹配,还能用来匹配集合。

匹配数组

示例

  • 依次修改代码定义以下三个数组
Array(1,x,y)   // 以1开头,后续的两个元素不固定
Array(0)	   // 只匹配一个0元素的元素
Array(0, ...)  // 可以任意数量,但是以0开头
  • 使用模式匹配上述数组

参考代码

val arr = Array(1, 3, 5)
arr match {case Array(1, x, y) => println(x + " " + y)case Array(0) => println("only 0")case Array(0, _*) => println("0 ...")case _ => println("something else")
}

匹配列表

示例

  • 依次修改代码定义以下三个列表
List(0)				// 只保存0一个元素的列表
List(0,...)   		// 以0开头的列表,数量不固定
List(x,y)	   		// 只包含两个元素的列表  
  • 使用模式匹配上述列表

参考代码

val list = List(0, 1, 2)list match {case 0 :: Nil => println("只有0的列表")case 0 :: tail => println("0开头的列表")case x :: y :: Nil => println(s"只有另两个元素${x}, ${y}的列表")case _ => println("未匹配")
}

匹配元组

示例

  • 依次修改代码定义以下两个元组
(1, x, y)		// 以1开头的、一共三个元素的元组
(x, y, 5)   // 一共有三个元素,最后一个元素为5的元组
  • 使用模式匹配上述元素

参考代码

val tuple = (2, 2, 5)
​
tuple match {case (1, x, y) => println(s"三个元素,1开头的元组:1, ${x}, ${y}")case (x, y, 5) => println(s"三个元素,5结尾的元组:${x}, ${y}, 5")case _ => println("未匹配")
}

变量声明中的模式匹配

在定义变量的时候,可以使用模式匹配快速获取数据

示例 | 获取数组中的元素

需求

  • 生成包含0-10数字的数组,使用模式匹配分别获取第二个、第三个、第四个元素

参考代码

val array = (1 to 10).toArray
val Array(_, x, y, z, _*) = array
​
println(x, y, z)

示例 | 获取List中的数据

需求

  • 生成包含0-10数字的列表,使用模式匹配分别获取第一个、第二个元素

参考代码

val list = (1 to 10).toList
val x :: y :: tail = listprintln(x, y)