scala-模式匹配和样例类

模式匹配和样例类

模式匹配

Scala没有Java中的switch case,它有一个更加强大的模式匹配机制,可以应用到很多场合。

Scala的模式匹配可以匹配各种情况,比如变量的类型、集合的元素、有值或无值。

模式匹配的基本语法结构:变量 match { case 值 => 代码 }

模式匹配match case中,只要有一个case分支满足并处理了,就不会继续判断下一个case分支了,不需要使用break语句。这点与Java不同,Java的switch case需要用break阻止。如果值为下划线,则代表不满足以上所有情况的时候如何处理。

模式匹配match case最基本的应用,就是对变量的值进行模式匹配。match是表达式,与if表达式一样,是有返回值的。

除此之外,Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配。

字符和字符串匹配

package hhb.cn.part07

import scala.util.Random

object MatchDemo {

  def main(args: Array[String]): Unit = {
    //对字符进行模式匹配
    val carStr = '6'
    carStr match {
      //只要有一个匹配上就会直接返回,不需要break。
      case '+' => println("11111111111")
      case '-' => println("22222222222")
      case '*' => println("33333333333")
      case '/' => println("44444444444")
      //这个表示上面的都没有匹配上,输出other,类似Java中default
      case _ => println("other")
    }
    //对字符串进行模式匹配
    val arr = Array("Hadoop", "Zookeeper", "Spark", "Scala")
    val project = arr(Random.nextInt(arr.length))
    println(project)
    project match {
      case "Hadoop" => println("this is Hadoop")
      case "Zookeeper" => println("this is Zookeeper")
      case "Spark" => println("this is Spark")
      case _ => println("Other")
    }
  }
}

守卫式匹配

 //守卫式匹配,添加if 判断
val c = '/'
val num = c match {
  case '+' => 1
  case '-' => 2
  case _ if c.equals('*') => 3
  case _ => 4
}
println(num)

匹配类型

Scala的模式匹配还有一个强大的功能,它可以直接匹配类型,而不是值。这一点是Java的switch case做不到的。
匹配类型的语法:case 变量 : 类型 => 代码,而不是匹配值的“case 值 => 代码”这种语法。

//匹配类型语法: case 变量 : 类型 => 代码
def typeMatch(x: Any): Int = {
  x match {
    case x: String => println("这是一个字符串类型")
    1
    case x: Int => println("这是一个整型类型")
    2
    case x: Boolean if x == false => println("这是布尔类型的false")
    3
    case x: Array[Int] => println("这是一个整型数组")
    4
    case _ => println("不知道是什么类型")
    5
}

匹配数组、元组、集合

package hhb.cn.part07

object MatchCollection {

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

    //对Array数组进行匹配,分别匹配:带有指定个数元素的数组、带有指定元素的数组、以某个元素开头的数据
    //    val array = Array(1, 3, 5, 7, 9) // 这是一个其他数组
    //val array = Array(1, 3, 5) //这是一个指定长度为3的数组,并且第一个元素为1,x y 分别为 :3   5
    //    val array = Array(1) //这是一个指定长度只有1的数组,而且元素就是1
    val array = Array(2) // 这是一个其他数组
    array match {
      case Array(1, x, y) => println(s"这是一个指定长度为3的数组,并且第一个元素为1,x y 分别为 :$x   $y")
      case Array(1) => println("这是一个指定长度只有1的数组,而且元素就是1")
      case Array(1, _*) => println("这是一个以1开头的数组")
      case _ => println("这是一个其他数组")
    }


    //对List集合进行匹配,分别匹配:带有指定个数元素的列表、带有指定元素的列表、以某个元素开头的列表、以某个元素结尾
    //    val list = List(1, 3, 4, 5)  // 这是一个以1开头的元素
    //    val list = List(1, 3) // 这个一个有指定个数元素的列表,1  3
    //    val list = List(1) // 这是一个指定长度只有1的列表,而且元素就是1
    val list = List(2, 4, "s") // 其他
    list match {
      case x :: y :: Nil => println(s"这个一个有指定个数元素的列表,$x  $y")
      case 1 :: Nil => println("这是一个指定长度只有1的列表,而且元素就是1")
      case 1 :: tail => println("这是一个以1开头的元素")
      //      case head :: 2 => println("这是一个以2结尾的元素")
      case _ => println("其他")
    }


    //对元组进行匹配
    var tuple = (2, 3, 2)
    tuple match {
      //以1开头,包含三个元素的元组
      case (1, x, y) => println(s"$x   $y")
      //以1结尾,包含三个元素的元组
      case (x, _, 1) => println(s"$x  ")
      case _ => println("其他")
    }
  }
}

样例类

case class样例类是Scala中特殊的类。当声明样例类时,以下事情会自动发生:

  • 主构造函数接收的参数通常不需要显式使用var或val修饰,Scala会自动使用val修饰
  • 自动为样例类定义了伴生对象,并提供apply方法,不用new关键字就能够构造出相应的对象
  • 将生成toString、equals、hashCode和copy方法,除非显示的给出这些方法的定义
  • 继承了Product和Serializable这两个特质,也就是说样例类可序列化和可应用Product的方法

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

此外,case class样例类中可以添加方法和字段,并且可用于模式匹配。

package hhb.cn.part07


class Amount

//样例类中主构造器的参数默认用val修饰
//样例类中自动生成apply方法
case class Test() extends Amount

case class Dollar(value: Double) extends Amount

case class Currency(value: Double, unit: String) extends Amount

case object Nothing extends Amount

object CaseClassDemo {

  def main(args: Array[String]): Unit = {
    judgeIdentity(Dollar(10.0))
    judgeIdentity(Currency(10.0, "123"))
    judgeIdentity(Nothing)
    judgeIdentity(Test())

  }

  /**
   * 样例类匹配
   *
   * @param amount
   */
  def judgeIdentity(amount: Amount): Unit = {
    amount match {
      case Dollar(value) => println("Dollar类型")
      case Currency(value, unit) => println("Currency类型")
      case Nothing => println("Nothing类型")
      case Test() => println("test")
    }
  }
}

Option与模式匹配

Scala Option选项类型用来表示一个值是可选的,有值或无值。

Option[T] 是一个类型为 T 的可选值的容器,可以通过get()函数获取Option的值。如果值存在,Option[T] 就是一个 Some。如果不存在,Option[T] 就是对象 None 。

Option通常与模式匹配结合使用,用于判断某个变量是有值还是无值。

object OptionDemo {

  val map: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 3)

  def getScore(name: String): Int = {

    val score = map.get(name)
    score match {
      //如果socre有值
      case Some(score) => score
      //如果score没有值
      case None => -1
    }
  }

  def main(args: Array[String]): Unit = {
    println(getScore("a"))
    println(getScore("d"))
  }

}
第六个模块错题集.png

你可能感兴趣的:(scala-模式匹配和样例类)