Scala(六)【模式匹配】

一.基本语法

在匹配某个范围的数据,需要在模式匹配中增加条件守卫。

语法

    变量 match {
      case 匹配条件 => 处理逻辑
      case 匹配条件 => 处理逻辑
      case 匹配条件 => 处理逻辑
      case _ => 其他处理 //case x => 其他条件  如果x不在箭头右边使用,则可以用_代替
    }

二.匹配固定值

语法

    变量 match {
      case 值1 => ...
      case 值2 => ...
      case _ => ....
    }

三.守卫

语法

    变量 match {
      //首先要满足指定类型,然后还要满足后面判断条件,才算匹配上
      case x: 类型 if 布尔表达式 =>....
    }

示例

    val x = 10
    x match {
      case i: Int if i >= 0 => i
      case j: Int if j < 0 => -j
      case _ => "type illegal"
    }

四.匹配类型

语法

    变量 match {
      case x: 类型1 =>... //如果x不需要在=>右边使用,可以用_代替
      case _: 类型2 =>...
      case x: 类型3 =>...
    } 

示例

    line match {
      case  =>
        println(s"string:${line}")
        x.length
      case x: Int =>
        println(s"int:${line}")
        x * x
      case x: Double =>
        println(s"double:${line}")
        x * x
      case x: Boolean =>
        println(s"boolean:${line}")
        if (x) 1 else 0
      case _ => println("其他类型")
    }

五.匹配集合

1.Array

示例

    val arr = Array[Any](1, "hello", 9)
    arr match {
      //匹配当前数组有4个元素
      case Array(x, y, z, e) => println(s"${x} $y $z $e")
      //匹配数组以0开头
      case Array(0, _*) => println("数组以0开头,元素的个数>=1")
      //匹配元素的类型
      case Array(x: Int, y: String, z: Int) => println(s"--- ${x} $y $z")
      //匹配数组有三个元素,只需要中间一个元素
      case Array(_, x, _) => println(s"${x}")
    }

2.List

示例

方式一:固定的List匹配

    list match {
      //list有多少元素,只有前两个会用到,其余可以用_代替。
      case List(x, y, _, _, _, _, _) =>
        println(s"list有7个元素,前两个 ${x} ${y}")
      //匹配List至少包含两个元素,且第一个元素是Int类型,第二个元素是String
      case List(x: Int, _*) =>
        println("第一个为Int,第二个为string")
      //匹配List的首位元素是固定值,后续的元素不要求
      //匹配List至少有一个元素
      case List(x, _*) =>
        println(s"首位元素是 ${x}")
      case _ => println("其他情况")
    }

方式二:::方式

    list match {
      //只有三个元素
      case x :: y :: z :: Nil => println("当前List有三个元素")
      //x是第一个元素,tail是剩余元素组成的List
      case x :: tail => println(s"匹配首位元素 ${x} 剩余部分:${tail}")
      //前两个元素Int类型x、Int类型,tail是其余元素组成的List
      case (x: Int) :: (y: Int) :: tail => println("匹配list至少两个元素,第一个为int,第二个int")
      case _ => println("+++++++++++++++++")
    }

泛型擦除

如果在匹配类型的时候,List中的泛型在运行的时候会擦除,导致 x:List[String] x:List[Int]的匹配效果一样

示例

    val arr = List[Int](1, "hello", false, 10.0, 2)
    arr match {
      case x: List[String] => println("....")
      case x: List[Int] => println("++++++")
    }
    //以上会匹配到第一个条件.

3.元祖

示例

    val t1: (Any, Any, Any) = ("zhangsan", 20, "shenzhen")
    t1 match {
      //匹配元组的元素,在匹配的时候元组的长度要和变量的元组长度要一致
      case (name: String, age: Int, address: String) =>
        println("name string,age int,address string")

      //要想匹配元组元素的类型,变量中数据的类型必须设置为Any
      case (name: Int, age: String, address: String) =>
        println("name int,age string,address string")
      case (name, age, address) => println(s"${name} ${age} ${address}")
    }

4.对象和样例类

1.样例类

定义语法:case class 类名([val/var] 属性名:类型,...)

​ 属性默认就是val修饰的

​ 直接用于模式匹配

创建样例类对象:case_class_类名(值,..)

示例

    //样例类
    case class Person(name: String, age: Int)

    val person: Any = Person("zhangsan", 20)
    //对象匹配
    person match {
      case Person(name, age) => println(s"name=${name}  age=${age}")
    }

2.普通类

如果想要让普通的class能够用于模式匹配。需要在伴生对象中创建unapply方法

    //普通类AA
    class AA(val name: String, val age: Int)
    object AA {
      def apply(name: String, age: Int) = new AA(name, age)
      //unapply如果返回的Some,代表能够匹配上,如果返回的是None,代表不能匹配上
      def unapply(arg: AA): Option[(String, Int)] = Some(arg.name, arg.age)
    }

六.偏函数

定义: 没有match关键字的模式匹配

语法

    val 函数名: PartialFunction[A, B] = {
      case...
      case...
    }
    //A: 入参的类型
    //B:返回值的类型

应用场景

    val list = List[(String, (String, (String, Int)))](
      ("A", ("1001", ("zhangsan", 20))),
      ("A", ("1002", ("lisi", 20))),
      ("A", ("1003", ("wangwu", 20))),
    )
    list.map({
      case (schoolName, (className, (studentName, age))) => age
    })

七.赋值匹配

示例

    val (name,age) = ("zhangsan",20)
    val List(x,y,z,_*) = List(1,2,3,4,5,6,7)

八.for循环匹配

示例

    val map = Map[String,Int](...)
    for( (K,V) <- map) {
      ...
    }
posted @ 2020-07-28 15:59  来自遥远的水星  阅读(107)  评论(0编辑  收藏  举报