37模式匹配-基础使用

28 阅读4分钟

(一)分析问题并解决

根据一个值输出另一个与之对应的值,很容易就想到if else 直接用 match case 来

package matchcase
/*
 * 任务:
 * 1·编写一个函数,输入省份编号,返回省份名称
 * 42湖北
 * 11北京
 */

object matchcase01 {
  def main(args: Array[String]): Unit = {

    println(getProvinceName(11))
    println(getProvinceName(42))
    println(getProvinceName(12))
  }

  def getProvinceName(code: Int): String = {
    code match {
      case 42 => "湖北"
      case 11 => "北京"
      case _ => "未知"
    }
  }
}

image.png

(二)match case的基本格式

格式如下

value match {

  case pattern1 => result1

  case pattern2 => result2

...

  case patternN => resultN

case _ => 其他

}

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

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

前面的匹配都是精准匹配:变量和值是相等的。但是呢,scala中的模式匹配的规则是非常强大的,不一定是精准的匹配值,还可以根据元组的元素的个数来匹配。

package matchcase

/*
* match case 的用法
* (1)类似于if else if 这种多分支选择结构,精确匹配值
* // 1. case _ 是不可省略的。如果匹配不成功,又没有case _ 程序会报错
* // 2. case _ 必须要放在最后。
* 匹配元组元素的数量
 */
object matchcase02 {
  def main(args: Array[String]): Unit = {
    val xiaohong = (100,100,100)
    val xiaoming = (89,98)

    getScore(xiaohong)
    getScore(xiaoming)
    getScore((1,2,3,4))
  }

  def getScore(score: Any): Unit = {
    score match {
      case (a, b, c) => println("元组中有三个元素: a = " + a + " b = " + b + " c = " + c)
      case (a, b) => println("元组中有两个元素: a = " + a + " b = " + b)
      case _ => println("未知")
    }
  }
}

image.png

(四)高阶匹配之变量类型匹配

除了格式匹配之后,还可以对变量的类型进行匹配。

格式如下:

对象名 match {

    case 变量名1:类型1  => 表达式1
case 变量名2:类型2  => 表达式2
case 变量名3:类型3  => 表达式3

    // 其他case语句...
casee _ => 表达式

}

如果变量名没有被使用到,可以使用_代替。 例如: _:Int =>

需求:
1.定义一个变量为Any类型,然后分别给它赋值不同的类型的数据。

2.对这个变量做模式匹配

package matchcase

object matchcase03 {
  def main(args: Array[String]): Unit = {
    testType(1)
    testType(1.1)
    testType("1")
  }

  def testType(i: Any): Unit = {
    i match {
      case _: Int => println("当前类型是: Int")
      case _: Double => println("当前类型是: Double")
      case _ => println("未知")
    }
  }
}

image.png

(五)高阶匹配之匹配元素特征

模式匹配还可以根据数组元素的个数,元素的特征来匹配。

例如如下的格式:

数组 match {

case Array(1,x,y) => 匹配到数组,长度为3,且第一个元素为1

case Array(0) =>匹配到数组:长度为1,且只有一个元素0
case Array(1,_*) =>匹配到数组:长度为n,第一个元素为1

    case _ => 其他

}

package matchcase

object matchcase04 {
  def main(args: Array[String]): Unit = {
    testType(Array(1,2,3))
    testType(Array(1,2,3,4))
    testType(Array(11,2,3,4))
    testType(Array(11,1,3,4))
  }

  def testType(arr: Any): Unit = {
    arr match {
      case Array(1,x,y) => println("arr是一个数组,有三个元素,第一个是1")
      case Array(1,x,y,z) => println("arr是一个数组,有四个元素,第一个是1")
      case Array(x,1,y,z) => println("arr是一个数组,有四个元素,第二个是1")
      case _ => println("未知")
    }
  }
}

image.png

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

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

对象 match {

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

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

    case _ => 其他

}

package matchcase
/* match case 的用法
* (1)类似于if else if 这种多分支选择结构,精确匹配值
* // 1. case _ 是不可省略的。如果匹配不成功,又没有case _ 程序会报错
* // 2. case _ 必须要放在最后。
* (2)匹配元组的数量
* (3)匹配数据类型
* (4)匹配数组
* (5)

 */
object matchcase05 {
  // 定义一个样例类:圆;它有一个属性:半径
  case class Circle(radius: Double)

  // 定义一个样例类:矩形;它有两个属性:长、宽
  case class Rectangle(width: Double, height: Double)

  // 定义一个方法,用来求圆形、矩形的面积
  def getArea(obj: Any): Unit = {
    obj match {
      case Circle(radius) => println("圆的面积是:" + radius * radius * 3.14)
      case Rectangle(width, height) => println("矩形的面积是:" + width * height)
      case _ => println("未知")
    }
  }

  def main(args: Array[String]): Unit = {
    getArea(Circle(2))
    getArea(Rectangle(2, 3))
  }
}

image.png