模式匹配-基础使用

53 阅读4分钟

问题导入

我们今天接到一个开发任务,就是根据身份证号码,输出这个人的籍贯。例如:42表示湖北,11表示北京

object day45 {
  /*
   match case
*  三大结构
*   1. 顺序结构:
*   2. 选择结构:
*     (1) if,if else if else;
*      (2) match case
*   1. case _ 不能省略,否则,匹配失败会报错。
*   2. case _ 必须写在最后。
*   3. 循环结构:
*     (2) for,
*      (3) while,do...while
   */
  def main(args: Array[String]): Unit = {

//    if(code=="42"){
//      privince="湖北"
//    }else if(code=="11"){
//      privince="北京"
//    }else{
//      privince="未知"
//    }
    val code="42"
    val province=code match{
      case "42"=>"湖北"
      case "11"=>"北京"
      case _=>"未知"
    }
    println(s"${code}对应的省份:${province}")
  }
}

match case的基本格式

Scala
value match {
  case pattern1 => result1
  case pattern2 => result2
...
  case patternN => resultN
  case _ => 其他
}

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

案例:

val num = 5
val result = num match {
  case 1 => "One"
  case 2 => "Two"
  case 3 => "Three"
  case 4 => "Four"
  case 5 => "Five"
  case _ => "Other"
}
println(result) 

案例:不同的水果宣传语

val str = "apple"
val output = str match {
  case "apple" => "It's an apple."
  case "banana" => "It's a banana."
  case _ => "It's some other fruit."
}

高阶匹配之元组元素数量

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

object day47 {
  /*
     match case 高阶匹配
     1. 匹配元组不同的元素的数量
     2.匹配数组特殊值
  */
  def main(args: Array[String]): Unit = {
    // 元组
    val t1 = (1,2)

    t1 match {
      case (a,b) => println(s"有二个元素${a}, ${b}")
      case _ => println("未知")
    }
    val arr1=Array(1,2,3)
    arr1 match{
      case  Array(1,x,y)=>println("属组,第一个元素是1,长度是3")
      case  _=>println("其他")
    }
  }
}

高阶匹配之匹配元素特征

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

例如如下的格式:

数组 match {

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

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

    case _ => 其他

}

案例如下:

object case03 {
  /*
  * match case 高阶匹配
  * 1.匹配元组不同的元素的数量
  * 2.匹配数组特殊值
  * 3.匹配变量的类型
  * */
  def matchType(value:Any):Unit = {
    value match {
      case x:Int => println(s"${x}是Int")
      case x:Double => println(s"${x}是Double")
      case _ => println("未知")
    }
  }

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

    matchType(1)
    matchType(1.1)
  }
}

//运行结果:
1Int
1.1Double

高阶匹配之匹配案例类

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

对象 match {

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

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

    case _ => 其他

}

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

案例如下:

object case04 {
  /*
  * match case 高阶匹配
  * 1.匹配元组不同的元素的数量
  * 2.匹配数组特殊值
  * 3.匹配变量的类型
  * 4.匹配杨丽丽
  * */
// 1.圆形类
  case class Cricle(radius:Double){}

//2.矩形类
case class Rectangle(width:Double,height:Double){}

  //封装一个求面积的方法
  def getArea(shape : Any): Double = {
    shape match {
      case Cricle(radius) => math.Pi * radius * radius
      case Rectangle(width, height) => width * height
      case _ =>0.0
    }
  }

  def main(args: Array[String]): Unit = {
    //1.实例化圆形对象
    val cricle =Cricle(2.0)
   //2.实例化矩形对象
    val rectangle =Rectangle(2.0,3.0)

    println(getArea(cricle))
    println(getArea(rectangle))
    }

}
//运行结果:
12.566370614359172
6.0

匹配for表达式

问:从Map中打印所有年龄为1983的创业者的信息。

object case05 {

  def main(args: Array[String]): Unit = {
    val m1 = Map(
      "马云 - 阿里巴巴" -> 1964,   "马化腾 - 腾讯" -> 1971,
      "李彦宏 - 百度" -> 1968,   "雷军 - 小米" -> 1969,
      "丁磊 - 网易" -> 1971,   "张一鸣 - 字节跳动" -> 1983,
      "刘强东 - 京东" -> 1974,   "程维 - 滴滴" -> 1983,
      "王兴 - 美团" -> 1979,   "周鸿祎 - 360" -> 1970,
      "黄峥 - 拼多多" -> 1980,   "李想 - 理想汽车" -> 1981,
      "何小鹏 - 小鹏汽车" -> 1977,   "贾跃亭 - 乐视" -> 1973,
      "陈天桥 - 盛大网络" -> 1973,   "周源 - 知乎" -> 1980,
      "王小川 - 搜狗" -> 1978
    )
    //请在m1这个Map 找出所有1983年出生的企业家
    for ((key, 1983) <- m1) {
      println(key)
    }

    for((key,value) <- m1){
      if(value == 1983)
        println(key)

    }


  }


}

//运行结果:
张一鸣 - 字节跳动
程维 - 滴滴
张一鸣 - 字节跳动
程维 - 滴滴

变量声明中的模式匹配

需求:现在有一个数组Array(1,2,3,4),我希望能定义三个变量,它们的值分别是数组中的第1,2,3个元素的值。

基础实现:

val arr = Array(1,2,3,4,5)

val x = arr(0)
val y = arr(1)
val z = arr(2)

println(x,y,z)

使用模式匹配的实现:

val arr = Array(1,2,3,4)  
val Array(x,y,z,_*) = arr  
println(x,y,z)

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