欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

以上内容仅供参考学习,如有侵权请联系我删除!
如果这篇文章对您有帮助,左下角的大拇指就是对博主最大的鼓励。
您的鼓励就是博主最大的动力!

相关标签: Scala学习指南