模式匹配

简介

匹配规则

匹配常量

def describe(x: Any) = x match {
    case 5 => "Int five"
    case "hello" => "String hello"
    case true => "Boolean true"
    case '+' => "Char +"
}

匹配类型

def describe(x: Any) = x match {
    case i : Int => i + 10
    case s : String => "String hello"
    case m: List[_] => "List"
    case c: Array[Int] => "Array[Int]"
    case someThing => "something else " + someThing
}

匹配数组

        for (arr <- Array(
            Array(0),
            Array(1, 0),
            Array(0, 1, 0),
            Array(1, 1, 0),
            Array(1, 1, 0, 1),
            Array("hello", 90))) { // 对一个数组集合进行遍历
            val result = arr match {
                case Array(0) => "0" //匹配Array(0) 这个数组
                case Array(x, y) => x + "," + y //匹配有两个元素的数组,然后将将元素值赋给对应的x,y
                case Array(0, _*) => "以0开头的数组" //匹配以0开头和数组
                case _ => "something else"
            }
            println("result = " + result)
        }
        result = 0
        result = 1,0
        result = 以0开头的数组
        result = something else
        result = something else
        result = hello,90

匹配列表

        for (list <- Array(
            List(0),
            List(1, 0),
            List(0, 0, 0),
            List(1, 0, 0),
            List(88))) {
            val result = list match {
                case List(0) => "0" //匹配List(0)
                case List(x, y) => x + "," + y //匹配有两个元素的List
                case List(0, _*) => "0 ..."
                case _ => "something else"
            }
            println(result)
        }
        1,0
        0 ...
        something else
        something else

匹配元组

        for (tuple <- Array(
            (0, 1),
            (1, 0),
            (1, 1),
            (1, 0, 2))) {
            val result = tuple match {
                case (0, _) => "0 ..." //是第一个元素是0的元组
                case (y, 0) => "" + y + "0" // 匹配后一个元素是0的对偶元组
                case (a, b) => "" + a + " " + b
                case _ => "something else" //默认
            }
            println(result)
        }
        0 ...
        10
        1 1
        something else

匹配对象

通过伴生对象定义unapply方法来进行对象之间的相互匹配

    def main(args: Array[String]): Unit = {
        // TODO - 模式匹配 - 匹配规则
        // 匹配对象
        // apply : Attribute => Object
        val user = getUser()
        // unapply : Object => Attribute
        user match {
            case User("zhangsan",40) => println("用户为张三")
            case _ => println("什么也不是")
        }
    }
    class User {
        var name:String = _
        var age:Int = _
    }
    object User {
        // Object => Attribute
        def unapply(user: User): Option[(String, Int)] = {
            Option( (user.name, user.age) )
        }
        // Attribute => Object
        def apply( name : String, age:Int ) = {
            val user = new User()
            user.name = name
            user.age = age
            user
        }
    }
    def getUser() = {
        User("zhangsan", 30)
    }

模式匹配用法

val (_, name, _) = (1, "zhangsan", 30)
println(name) ==> zhangsan 
val map = Map(
    ("a", 1), ("b", 2), ("c", 3)
)
for ( (k, 2) <- map ) {
    println( k ) ==> b
}
        val list = List(
            (("河北", "鞋"), 10),
            (("河北", "衣服"), 20),
            (("河北", "电脑"), 15),
        )
        list.map(
            (t) => {
                t
            }
        )
        // 下面的代码中,使用模式匹配需要注意:
        // 1. 匹配数据时,需要使用case关键字
        // 2. case分支可能存在多个,那么需要将map的小括号换成大括号
        val list1 = list.map {
            case ((prv, item), cnt) => {
                (prv, (item, cnt * 2))
            }
        }

样例类

在编译时,会自动生成大量的方法

  1. 样例类会自动实现可序列化接口
  2. 样例类的构造参数直接能够作为属性使用,但是不能修改,如果想要修改,需要将参数使用var声明
  3. 增加和重写了大量的方法
  4. 样例类自动生成伴生对象,而且其中自动声明了apply,unapply
    def main(args: Array[String]): Unit = {
        val user = getUser()
        user.name = "lisi"
        user match {
            case User("zhangsan",40) => println("用户为张三")
            case _ => println("什么也不是")
        }
    }
    case class User(var name:String, age:Int)
    def getUser() = {
        User("zhangsan", 40)
    }

偏函数

以偏概全

发表回复