Scala深入学习之模式匹配
程序员文章站
2022-06-06 23:28:59
...
模式匹配是检查某个值(value)是否匹配某一个模式的机制,一个成功的匹配同时会将匹配值解构为其组成部分。它是Java中的switch语句的升级版,同样可以用于替代一系列的 if/else 语句。
一、语法
一个模式匹配语句包括一个待匹配的值,match关键字,以及至少一个case语句。
package matchDemo.mode
import scala.io.StdIn
/**
* @author : 蔡政洁
* @email :[email protected]
* @date : 2020/11/17
* @time : 12:35 下午
* 完成Scala中模式匹配的学习
*/
object MatchCaseOps1 {
def main(args: Array[String]): Unit = {
// swichOps()
// yeildOps() // 简写
// typeOps() // 类型的模式匹配
collectionOps() // 集合操作
}
/*
* 学习模式匹配去模拟Java中的switch语法
* char ch = '='
* switch(ch){
* case '+'
* ...
* break;
* case '-'
* ...
* break;
* ...
* default:
* ...
* break;
* }
*
*/
def swichOps(): Unit ={
println("请从控制台输入一个字符:")
val ch:Char = StdIn.readChar()
var sign = 0
ch match {
case '+' => sign = -1
case '-' => sign = 1
case '*' => sign = -2
case '/' => sign = 2
case _ => sign = 0 // Java中default操作
}
println("sign:"+sign)
}
// 模式匹配是一个表达式,因此是有返回值的
def yeildOps(): Unit ={
println("请从控制台输入一个字符:")
val ch:Char = StdIn.readChar()
var sign = ch match {
case '+' => -1
case '-' => 1
case '*' => -2
case '/' => 2
case _ => 0 // Java中default操作
}
println("sign:"+sign)
}
def typeOps(): Unit ={
class Person(name:String,age:Int){
}
class Worker(name:String,age:Int) extends Person(name,age){
def work(): Unit ={
println(s"工人${name},年龄为${age}正在工作")
}
}
class Student(name:String,age:Int) extends Person(name,age){
def study(): Unit ={
println(s"学生${name},年龄为${age}正在学习")
}
}
def doSth(person: Person): Unit ={
// 类型匹配--类型检查
person match {
case worker: Worker => worker.work()
case student: Student => student.study()
case _ => println("没有匹配到具体类型")
}
}
doSth(new Worker("alex",23))
}
def collectionOps(): Unit ={
println("----------匹配字符串----------")
val str = "hello world"
for (ch <- str){
ch match {
case ' ' => println(",")
case _ => println(ch)
}
}
println("----------匹配其他集合----------")
val array = Array(0,1)
array match {
// 匹配当前数组,如果只有两个元素,成功,就依次赋值给x,y
case Array(x,y) => println(s"x=${x},y=${y}")
case Array(0,_ *) => println("匹配该数组,首元素为0")
case _ => println("other.")
}
}
}
二、案例类
案例类非常适合用于模式匹配。示例代码:
package matchDemo.mode
/**
* @author : 蔡政洁
* @email :[email protected]
* @date : 2020/11/17
* @time : 1:33 下午
* 模式匹配之匹配case class样例类
*/
object MatchOps2 {
def main(args: Array[String]): Unit = {
caseOps()
}
def caseOps(): Unit ={
abstract class Expr // 抽象类,代表了表达式
case class Var(name:String) extends Expr
case class UnOp(expr: Expr,operator: String) extends Expr
case class Number(num:Double) extends Expr
// 3+4
case class BinOp(val left: Expr,operator: String,var right: Expr) extends Expr
def test(expr: Expr): Unit ={
expr match {
case Var(name) => println("var:"+name)
case Number(num) => println("number:"+num)
case UnOp(Var(name),"+") => println(name + "+")
case BinOp(Number(num1),"+",Number(num2)) => println(num1+num2)
case BinOp(Number(num1),"-",Number(num2)) => println(num1-num2)
case BinOp(Number(num1),"*",Number(num2)) => println(num1*num2)
case BinOp(Number(num1),"/",Number(num2)) => println(num1/num2)
case _ => println(expr)
}
}
val binOp = BinOp(Number(3.0),"*",Number(4.2))
binOp.right = Number(3.2)
test(binOp)
}
}
运行结果:
9.600000000000001
三、密封类
特质(trait)和类(class)可以用sealed标记为密封的,这意味着其所有子类都必须与之定义在相同文件中,从而保证所有子类型都是已知的。
package matchDemo.mode
/**
* @author : 蔡政洁
* @email :[email protected]
* @date : 2020/11/17
* @time : 2:12 下午
* Scala中使用case class来模拟枚举操作
*/
object EnumerationOps {
def main(args: Array[String]): Unit = {
accrossRoad(TrafficLight.GREEN)
println("------使用case class来模拟枚举------")
accrossRoad(RED("hongdeng"))
}
def accrossRoad(ligth:TrafficLight.Value): Unit ={
ligth match {
case TrafficLight.RED => println("行车不规范,亲人两行泪")
case TrafficLight.YELLOW => println("快人5秒钟,快人一辈子")
case TrafficLight.GREEN => println("开开心心开出去,平平安安开回来")
}
}
def accrossRoad(ligth:Light): Unit ={
ligth match {
case RED(name) => println(name+"行车不规范,亲人两行泪")
case YELLOW(name) => println(name+"快人5秒钟,快人一辈子")
case GREEN(name) => println(name+"开开心心开出去,平平安安开回来")
}
}
// 使用Scala传统的方式来定义一个枚举,得到RED其实是TrafficLight.Value这种类
object TrafficLight extends Enumeration{
val RED,YELLOW,GREEN = Value
}
}
/*
scala中对于如果说一个类的子类都是已知的,我们可以使用一个sealed关键字来进行修饰
表示该类是密封,刚好和枚举类含义契合,枚举,可以,一一列举
*/
sealed class Light(name:String)
case class RED(name:String) extends Light(name)
case class YELLOW(name:String) extends Light(name)
case class GREEN(name:String) extends Light(name)
运行结果:
开开心心开出去,平平安安开回来
------使用case class来模拟枚举------
hongdeng行车不规范,亲人两行泪
四、option操作
package matchDemo.mode
/**
* @author : 蔡政洁
* @email :[email protected]
* @date : 2020/11/17
* @time : 2:31 下午
* scala模式匹配之option操作
*/
object MatchOps3 {
def main(args: Array[String]): Unit = {
val map = Map[String,String](
"China"->"Beijing",
"Japan"->"Tokyo",
"India"->"XDL"
)
val capitalOption:Option[String] = map.get("China")
capitalOption match {
case Some(capital) => println("Capital is"+capital)
case None => println("所查国家不存在")
}
}
}
运行结果:
Capital isBeijing
以上内容仅供参考学习,如有侵权请联系我删除!
如果这篇文章对您有帮助,左下角的大拇指就是对博主最大的鼓励。
您的鼓励就是博主最大的动力!
上一篇: 不要让敌人捉了奸