模式匹配-基础使用

69 阅读3分钟

分析问题并解决

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

object ProvinceCodeLookup {

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

        val code = "42"

        val provinceName = getProvinceName(code)

        println(provinceName)

    }

    def getProvinceName(code: String): String = {

        if (code == "42") {

            "湖北"

        } else if (code == "33") {

            "浙江"

        } else if (code == "11") {

            "北京"

        } else if (code == "31") {

            "上海"

        } else {

            "未找到对应的省份"

        }

    }

}

直接用 match case 来改造。

    def getProvinceName(code: String): String = code match {

        case "42" => "湖北"

        case "33" => "浙江"

        case "11" => "北京"

        case "31" => "上海"

        case _ => "未找到对应的省份"

    }

match case的基本格式

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)

高阶匹配之元组元素数量

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

val t1 = (2,3)

val t1 = (2,3,4)

val t1 = (2,3,4,5)  
def matchAmount(value: Any): Unit =  
   t1 match {

     case (first, second) => "有两个元素"

     case (x1,x2,x3) => "有三个元素"

     case _ => "其他情况"

}  
}

matchAmount(t1)

高阶匹配之匹配元素特征

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

例如如下的格式:

数组 match {

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

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

    case _ => 其他

}


val arr1 = Array(0)  //长度为1  
val arr2 = Array(1,2,3)// 首元素为1  
val arr3 = Array(0,2,8,10,11)  
val arr4 = Array(1,2,8,10,11)  
  
arr4 match {  
  case Array(1,x,y) => println("匹配到数组,长度为3,且第一个元素为1")  
  case Array(0)=>println("匹配到数组:长度为1,且只有一个元素0")  
  case Array(0,_*) =>println("匹配到数组:长度为n,第一个元素为0")  
  case _ => println("其他")  
}

高阶匹配之变量类型匹配

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

格式如下:

对象名 match {

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

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

}

如果变量名没有被使用到,可以使用_代替。 例如: _:Int => 需求:
1.定义一个变量为Any类型,然后分别给它赋值不同的类型的数据。

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

def processValue(value: Any): Unit =

value match {

    case i: Int => println(s"这是一个整数:$i")

    case d: Double => println(s"这是一个双精度浮点数:$d")

    case s: String => println(s"这是一个字符串:$s")

    case b: Boolean => println(s"这是一个布尔值:$b")

    case _ => println("这是其他类型")

}  
}  
matchType(5)  
matchType("Hello")

高阶匹配之匹配案例类

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

对象 match {

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

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

    case _ => 其他

}

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

case class Circle(radius: Double)

case class Rectangle(width: Double, height: Double)  
def calculateArea(shape: Any): Double = shape match {

    case Circle(r) => Math.PI * r * r

    case Rectangle(w, h) => w * h

}

val circle = Circle(3.0)

val rectangle = Rectangle(4.0, 5.0)

println(calculateArea(circle))

println(calculateArea(rectangle))