21.Scala模式匹配

Scala模式匹配

Scala中的模式匹配类似于java中的switch语法,但是java中的switch只能做分支运算,在Scala中的模式匹配能做更多。模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分支开始,如果匹配成功,那么执行对应的逻辑代码,并且跳出判断逻辑,如果匹配不成功,继续执行下一个分支进行判断。如果所有case都不匹配,那么会执行case _分支,如果没有case _会抛出MatchError。

模式守卫

模式守卫实际就是对输入值的一个判断,后面可以加入类型之类的。如果满足则执行case之中的语句。9

 def main(args: Array[String]): Unit = {
        def abs(x :Int) = {
            x match {
                case i  if i >=0 => i
                case j  if j <=0 => -j
                case _ => "wrong value"
            }
        }
        val value: Any = abs(-4)
        println(s"value = ${value}")
    }

匹配类型

匹配常量

    def describe(x: Any) = x match {

        case 5 => "Int five"

        case "hello" => "String hello"

        case true => "Boolean true"

        case '+' => "Char +"

        case _ =>"not any thing"

    }

匹配类型

object TestMatchClass {

    def describe(x: Any) = x match {

        case i: Int => "Int"
        case s: String => "String hello"
        case m: List[_] => "List"
        case c: Array[Int] => "Array[Int]"
        // 代替的是下划线
        case someThing => "something else " + someThing
    }

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

        //在类型匹配时不考虑泛型
        println(describe(List(1, 2, 3, 4, 5)))

        //数组例外,可保留泛型,Array之所以例外是由于其在字节码中使用的是String[3]构造的数组
        println(describe(Array(1, 2, 3, 4, 5, 6)))
        println(describe(Array("abc")))
    }
}

匹配数组

object TestMatchArray {

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

        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)
        }
    }
}

匹配列表

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

       //list是一个存放List集合的数组
       //请思考,如果要匹配 List(88) 这样的只含有一个元素的列表,并原值返回.应该怎么写
       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 first :: second :: rest => println(first + "-" + second + "-" + rest)

               case _ => "something else"

           }

           println(result)
       }
   }
}

匹配元组

object TestMatchTuple {

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

        //对一个元组集合进行遍历
        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)
        }
    }
}

模式匹配的应用场景

object ScalaMatch02 {
    def main(args: Array[String]): Unit = {
        val list = List(("hello1", 1, 20), ("hello2", 1, 20), ("hello3", 1, 30))
        for ((word, no, 20) <- list) {
            println(word)
        }

        val stringToInt = Map(("a", 1), ("b", 2), ("c", 3))
        //        val stringToInt1: Map[String, Int] = stringToInt.map((s: (String, Int)) => {
        //            (s._1, s._2 * 2)
        //        })

        // 在参数只有一个的场合可以使用模式匹配
        // 使用模式匹配时需要将方法的小括号变为大括号
        // case不能省略
        val stringToInt1: Map[String, Int] = stringToInt.map{
            case (word,count) => {
                (word, count * 2)
            }
        }

        // 取下划线大于等于2

        println(stringToInt1)


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

        // 只会对满足条件的一部分数据做操作,并不会对所有的数据做操作
        // 将集合中Int类型的元素加一,并去掉字符串
        val list: List[Any] = List(1, 2, 3, 4, 5, "Int")

        val list1: List[Any] = list.map(s => {
            s match {
                case num: Int => num + 1
                case d => d
            }
        })

        val list2: List[Any] = list1.filter(data => data.isInstanceOf[Int])

    }
}

样例类

package cn.lpc.Cheapter08

// 样例类,作用就是为了模式匹配
// 和普通类的声明方式不一样

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


    }
}

//    case class UserMatch(){
//
//    }

// 样例类使用case关键字声明
// 样例类构造参数列表不能省略
// 当类声明为样例类时,编译器会自动生成伴生类和伴生对象
// 样例类和普通一致,在里面定义的apply方法是一个普通方法
// 样例类如果声明构造参数,等同于声明类的属性,而且该属性不可改变
// 等同于普通类在class UserMatch(val name : String){},可以修改修饰符号
// 工作中声明的类,一般声明样例类。
/*case class Student( name : String){

    def say()={
        println(name)
    }
}*/

匹配对象

    def mian():Unit {

        //匹配对象时,首先会将对象传递到类的伴生对象的unapply方法。
        // unapply方法会返回Opthion类型的数据,然后进行数据对比,如果全部比对成功,那么会执行对应的逻辑
        // 在Scala中采用样例类可以更简单,不需要自定义unapply方法

         

        val user :User = User("zhangsan", 11)
        var result = user match{
            case User("zhangsan", 11) =>"yes"
            case => "no"
        }



    }

偏函数

函数只对满足条件的数据进行操作,不会对所有数据进行操作 在Scala中可以使用case可以简写偏函数

// 与map不同的的地区在于可以不要对不满足的数据做操作,map需要对全量数据做操作
list.collect{
    case num:Int=>num+1
}

异常

object Scala_Exception {
    def main(args: Array[String]): Unit = {
        // Scala中采用的异常也是模式匹配
        // Scala中异常没有分类,所以不需要再编译时提示
        // 而且也不需要显示的用try,catch进行捕捉
        // 一般将范围小的异常放置在前面捕捉,范围大的放置在后面

        val i = 0

        try{
            val s = 10 /i
        }catch {
            case e :ArithmeticException => println("除数为0")
            case ex : Exception => println("捕捉到异常")
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值