【图文详细 】Scala——模式匹配

版权声明:版权声明:本文为博主原创文章,转载请附上博文链接! https://blog.csdn.net/qq_42246689/article/details/85146621

5、Scala 的模式匹配 

Scala 有一个十分强大的模式匹配机制,可以应用到很多场合:如 switch 语句、类型检查等。

并且 Scala 还提供了样例类,对模式匹配进行了优化,可以快速进行匹配 
 

5.1、匹配字符串

object CaseDemo01 extends App{
   val arr = Array("huangbo", "xuzheng", "wangbaoqiang","xxxx")
   val name = arr(Random.nextInt(arr.length)) 
 // name模式匹配字符串 
  name match {
     case "huangbo" => println("影帝来也...")
     case "xuzheng" => println("喜剧笑星来了...")
     case "wangbaoqiang" => println("实力干将来也...")
     case _ => println("谁...???")
   }
 } 

5.2、匹配类型 

object CaseDemo02 extends App{ 
  //val v = if(x >= 5) 1 else if(x < 2) 2.0 else "hello" 
  val arr = Array("hello", 1, 2.0, CaseDemo) 
  val v = arr(Random.nextInt(4)) 
  println(v) 
 
  // 模式匹配
   v match { 
    case x: Int => println("Int " + x) 
    case y: Double if(y >= 0) => println("Double "+ y) 
    case z: String => println("String " + z) 
    case _ => throw new Exception("not match exception") 
  } 
} 
 
case class CaseDemo() 

注意:case y: Double if(y >= 0) => ... 模式匹配的时候还可以添加守卫条件。如不符合守卫条件,将掉入 case _中 

5.3、匹配数组、元组、集合

object CaseDemo03 extends App{ 
 
  val arr = Array(1, 3, 5) 
  arr match { 
    case Array(1, x, y) => println(x + " " + y) 
    case Array(0) => println("only 0") 
    case Array(0, _*) => println("0 ...") 
    case _ => println("something else") 
  } 
 
  val lst = List(3, -1) 
  lst match { 
    case 0 :: Nil => println("only 0") 
    case x :: y :: Nil => println(s"x: $x y: $y") 
    case 0 :: tail => println("0 ...") 
    case _ => println("something else") 
  } 
 
  val tup = (2, 3, 7) 
  tup match { 
    case (1, x, y) => println(s"1, $x , $y") 
    case (_, z, 5) => println(z) 
    case  _ => println("else") 
  } 
}

注意:在 Scala 中列表要么为空(Nil 表示空列表)要么是一个 head 元素加上一个 tail 列表。

9 :: List(5, 2)  :: 操作符是将给定的头和尾创建一个新的列表

注意::: 操作符是右结合的,如 9 :: 5 :: 2 :: Nil 相当于 9 :: (5 :: (2 :: Nil)) 

5.4、样例类 
在 Scala 中样例类是一中特殊的类,可用于模式匹配。

case class 是多例的,后面要跟构造参数,case object 是单例的 

object CaseDemo04 extends App{ 
 
  val arr = Array(CheckTimeOutTask, HeartBeat(123), SubmitTask("0001", "task1")) 
 
  arr(Random.nextInt(arr.length)) match { 
    case SubmitTask(id, name) => { 
      println(s"$id, $name") 
    } 
    case HeartBeat(time) => { 
      println(time) 
    } 
    case CheckTimeOutTask => { 
      println("check") 
    } 
  } 
} 
 
case class SubmitTask(id: String, name: String) 
case class HeartBeat(time: Long) 
case object CheckTimeOutTask 

当一个类被声名为 case class 的时候,scala 会帮助我们做下面几件事情:

1、构造器中的参数如果不被声明为 var 的话,它默认的话是 val 类型的,但一般不推荐将 构造器中的参数声明为 var

2、自动创建伴生对象,同时在里面给我们实现子 apply 方法,使得我们在使用的时候可以 不直接显示地 new 对象

3、伴生对象中同样会帮我们实现 unapply 方法,从而可以将 case class 应用于模式匹配 apply 方法接受参数返回对象,unapply 方法接收对象返回参数

4、实现自己的 toString、hashCode、copy、equals 方法

5、case class 主构造函数里面没有修饰符,默认的是 val

除此之此,case class 与其它普通的 scala 类没有区别 

object UnapplyTest { 
 
  // 接收参数,返回对象, 一般用作工厂
   def apply(value: Double, unit: String): Currency = new Currency(value, unit) 
 
  // 接收对象,返回参数, 一般用于模式匹配 
 def unapply(currency: Currency): Option[(Double, String)] = { 
    if (currency == null){ 
      None 
    } 
    else{ 
      Some(currency.value, currency.unit) 
    } 
  } 
} 
 
class Currency(val value: Double, val unit: String) { 
}

5.5、Option 类型 

在 Scala 中 Option 类型样例类用来表示可能存在或也可能不存在的值(Option 的子类有 Some 和 None)。

Some 包装了某个值,None 表示没有值

object OptionDemo { 
 
  def main(args: Array[String]) { 
 
    val map = Map("a" -> 1, "b" -> 2) 
    val v = map.get("b") match { 
      case Some(i) => i 
      case None => 0 
    } 
    println(v) 
 
    // 更好的方式
     val v1 = map.getOrElse("c", 0) 
    println(v1) 
  } 
}

5.6、偏函数 
被包在花括号内没有 match 的一组 case 语句是一个偏函数,

它是 PartialFunction[A, B]的一 个实例,A 代表参数类型,B 代表返回值类型,常用作输入模式匹配

object PartialFuncDemo  { 
  // 偏函数
 
  def func1: PartialFunction[String, Int] = { 
    case "one" => 1 
    case "two" => 2 
    case _ => -1 
  } 
  // 普通函数的 模式匹配 实现
 
  def func2(num: String) : Int = num match { 
    case "one" => 1 
    case "two" => 2 
    case _ => -1 
  } 
 
  def main(args: Array[String]) { 
    println(func1("one")) 
    println(func2("one")) 
  } 
}

总结: 偏函数,就是用来做模式匹配的 

猜你喜欢

转载自blog.csdn.net/qq_42246689/article/details/85146621