模式匹配-基础使用

47 阅读4分钟

(一)分析问题并解决

根据一个值输出另一个与之对应的值,很容易就想到if else

def main(args: Array[String]): Unit = {
    val code = 52
    var province = " "
    if(code == 42) {
      province = "湖北省"
    } else if (code == 52) {
      province = "四川省"
    }else{
      province = "未知"
    }
    println(province) 
  }
}

(二)match case的基本格式

val code = 42
val province = code match {
  case 42 => "湖北省"
  case 52 => "四川省"
  case _ => "未知"
}
println(province)

执行流程是:如果value匹配到了pattern1,就执行结果1,如果都没有匹配到,就执行 _ 对应的内容。

object matchcase02 {

  def main(args: Array[String]): Unit = {
    // 输入1,输出单词one
    // 输入2,输出单词two
    // 输入3,输出单词three
    // 输入其他,输出单词other

    // 1.如果能精准匹配成功,就会执行后面的代码
    // 2.case _ 他表示可以匹配任意的内容。一定要放在最后一条
    // 3.case _ 不能省略:如果匹配不成功,就会报错   10 (of class java.lang.Integer)

    // 1.从键盘获取数字
    val code = 10
    // 2. 使用matchcase进行匹配
    code  match {
      case 1 => println("one")
      case 2 => println("two")
      case _ => println("未知")
    }
  }
}

(三)案例:不同的数据类型

/*
* match case
* 1.匹配精准度
* 2.匹配数据类型
* */
object matchcase03 {

  def processValue(value:Any):Unit = {
    value match {
      case x: Int => println("Int")
      case x: String => println("String")
      case _: Int => println("other")
    }
  }

  def main(args: Array[String]): Unit = {
    val obj = 10
    processValue(obj)
  }
}

(四)高阶匹配之元组元素数量

前面的匹配都是精准匹配:变量和值是相等的。

/*
* match case
* 1.匹配精准度
* 2.匹配数据类型
* 3.匹配元素的个数
* */
object matchcase03 {

  def processValue(value:Any):Unit = {
    value match {
      case x: Int => println("Int")
      case x: String => println("String")
      case _: Int => println("other")
    }
  }

  def processNum(value:Any):Unit = {
    value match {
      case (a,b,c) => println(s"三个元素的元组,第一个元素是${a}")
      case (x,y) => println("两个元素的元组")
      case _ => println("其他")
    }
  }

  def main(args: Array[String]): Unit = {
//    val obj = 10
//    processValue(obj)

    processNum( (1,2) )
    processNum( (1,2,3) )

  }
}

结果如下:

两个元素的元组
三个元素的元组,第一个元素是1

但是呢,scala中的模式匹配的规则是非常强大的,不一定是精准的匹配值,还可以根据元组的元素的个数来匹配。

/*
* match case
* 1.匹配精准度
* 2.匹配数据类型
* 3.匹配元素的个数
* 4.匹配数组元素个数,元素特征
* */
object matchcase04 {
  def matchArray(arr:Any):Unit = {
    arr match {
      case Array(x,y) => println("匹配到有两个元素的数组", x, y)
      case Array(1,b,c) => println("匹配到有三个元素的数组,第一个元素是1")
      case Array(a,b,c) => println("匹配到有三个元素的数组", a, b, c)
      case Array(10,_*) => println("第一个元素是10,元素个数有任意个")
      case _ => println("没有匹配到")
    }
  }

  def main(args: Array[String]): Unit = {
    val arr1 = Array(1,2,3)
    val arr2 = Array(2,2,3)
    val arr3 = Array(10,2,3,1)
    matchArray(arr1)
    matchArray(arr2)
    matchArray(arr3)
  }
}

结果如下:

匹配到有三个元素的数组,第一个元素是1
(匹配到有三个元素的数组,2,2,3)
第一个元素是10,元素个数有任意个

(五)高阶匹配之匹配案例类

模式匹配还根据案例类的不同,匹配不同的案例类和其中的字段信息。例如格式

对象 match {

case 样例类类型1(字段1,字段2)=> 表达式

case 样例类类型2(字段1,字段2,字段3)=> 表达式

    case _ => 其他

}

注意:样例类1中的字段个数要与之对应。

/*
* match case
* 1.匹配精准度
* 2.匹配数据类型
* 3.匹配元素的个数
* 4.匹配数组元素个数,元素特征
* 5.匹配案例类
* */
object matchcase05 {

  case class Circle(r:Double)
  case class Rectangle(w:Double,h:Double)

  def  calculateArea(shape:Any):Double = {
    shape match {
      case Circle(r) => 3.14 * r * r
      case Rectangle(w,h) => w * h
      case _ => 0.0
    }
  }

  def main(args: Array[String]): Unit = {
    val circle = Circle(2.0)
    val rectangle = Rectangle(2.0,3.0)
    println(calculateArea(circle))
    println(calculateArea(rectangle))
  }
}

结果如下:

12.56
6.0

当传入Circle类型时,匹配case Circle(r)并按照圆的面积公式计算;当传入Rectangle类型时,匹配case Rectangle(w, h)并按照矩形面积公式计算。

(六)高阶匹配之变量声明时的匹配

其中: _*表示多个其他的元素值。

/*
* match case
* 1.匹配精准度
* 2.匹配数据类型
* 3.匹配元素的个数
* 4.匹配数组元素个数,元素特征
* 5.匹配案例类
* 6.变量声明时的匹配
* */
object matchcase06 {
  def main(args: Array[String]): Unit = {
    val arr = Array(1,2,3,4,5)
    // 定义3个变量:x,y,z 保存数组中的前三个元素的值
//    val x = arr(0)
//    val y = arr(1)
//    val z = arr(2)
//    println(x,y,z)

    val Array(x,y,z,_*) = arr
    println(x,y,z)
  }
}

结果如下:

(1,2,3)