一、语法
一个模式匹配语句包括一个待匹配的值,match关键字,以及至少一个case语句。
package matchDemo.mode import scala.io.StdIn /** * @author : 蔡政洁 * @email :caizhengjie888@icloud.com * @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 :caizhengjie888@icloud.com * @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 :caizhengjie888@icloud.com * @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 :caizhengjie888@icloud.com * @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