第14章 模式匹配和样例类

来源:互联网 发布:c语言手势识别算法 编辑:程序博客网 时间:2024/06/05 00:37

样例类

这里写图片描述
这里写图片描述

在Scala中样例类是一中特殊的类,可用于模式匹配。
case class是多例的,后面要跟构造参数,case object是单例的

在case class中,主构造器中的参数不用显示地使用val,var来定义成员变量,主构造器中的参数默认是val,且不建议用var
case class SubmitTask(id: String, name: String)
case class HeartBeat(time: Long)
case object CheckTimeOutTask

获得一个case class的实例对象,不用显示的new,而是直接“类名(参数)”就行了,其实调用了MyUser类的对象中的apply方法
val u = MyUser(“chii”, “123456”)

copy 方法:创建一个与现有值相同的新对象。创建过程中可以指定要修改的值 如:val ue = u.copy(name = “chiichii”)

密封类:编译期所有子类都是可知的,编译器可以检查模式语句的完整性。
sealed abstract class Amout
case class Dollar(value: Double) extends Amount
密封类的所有子类(Dollar)都必须在与该密封类(Amount)相同的文件中。

模式匹配

守卫

val arr = Array("hello", 1, -2.0)val elem = arr(Random.nextInt(arr.length))elem match {    case x: Int => println("--")    //守卫     必须Doulbe 和 y>=0都要满足    case y: Double if (y >= 0) => println("--")    case _ => throw new Exception("not match exception")}

变量声明中的模式

val (x,y) = (1, 2)//将商赋值给q,余数赋值给rval (q,r) = BigInt(10) /% 3      val Array(first, second, _*) = arr

for表达式中的模式

import scala.collection.JavaConversions.propertiesAsScalaMapfor ((k, v) <- System.getProperties)  println(k + "->" + v)//v不为""的将匹配失败被忽略for ((k, "") <- System.getProperties)//可以使用守卫for ((k, v) <- System.getProperties if v == "")  println(k + "->" + v)

模式匹配样例

值匹配

//写法一: var a = 1 a match {   case 1 => println("it is 1")   case 2 => println("it is 2")   case _ => println("other thing") }//写法二: var a = 2 a match {   case x if x == 1 => println("it is 1")   case x if x == 2 => println("it is 2")   case _ => println("it is other num") } //函数定义方式一: def test(a: Int) {   println("调用函数...")   a match {     case 1 => println("it is 1 -- in function")     case 2 => println("it is 2 -- in function")     case _ => println("other thing -- in function")   } } //函数定义方式二: def test(a: Int) =   a match {     case 1 => println("it is 1 -- in function")     case 2 => println("it is 2 -- in function")     case _ => println("other thing -- in function") //函数调用 test(3)

基本类型匹配

//示例一: def t(obj: Any) = obj match {     //case class   case x: String => println("it is a String");obj   case x: Int => println("it is a Int");obj   case _ => println("it is other");obj }//Int t(5) //返回输入的内容 print(t(5))示例二:val arr = Array("hello", 1, -2.0)val elem = arr(Random.nextInt(arr.length))elem match {    case x: Int => println("--")    //必须Doulbe 和 y>=0都要满足    case y: Double if (y >= 0) => println("--")    case _ => throw new Exception("not match exception")}

精准匹配->集合(数组)

//Array(List等也可以使用这种方式)//从上到下匹配,只要匹配到了一个就不会往下执行了,即使是模糊匹配的,下面的有的完美匹配,也按模糊匹配的val arr = Array(0, 1, 5)arr match {  case Array(1, x, y) => println(x + " " + y)  case Array(0, 1, 5) => println("only 0")  case Array(0, _*) => println("0 ...")  case _ => println("something else")}//List(推荐)val lst = List(0,3, 111)lst match {  case 0 :: Nil => println("only 0")  //list只有0  case x :: y :: Nil => println(s"x: $x y: $y")//只有两个值x,y  case 0 :: a => println("0 ...")//第一个为0,后面的随便多少个  case _ => println("something else")}//Tup(case用来匹配的参数个数必须和tup定义的大小一样)val tup = (1, 3, 5)tup match {  case (1, x, y) => println(s"hello 123 $x , $y")  case (_, z, 5) => println(z)  case  _ => println("else")}//Map//在Scala中Option类型用样例类来表示可能存在或也可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值valm = Map("a" -> 1, "b" -> 2)var x:Int = 0m.get(x) match {  case Some(x) => println(x)  case None => println("key not exists...")  case _ => println("other...")}

这里写图片描述

case样例匹配

case class SubmitTask(id: String, name: String)case class HeartBeat(time: Long)case object CheckTimeOutTaskabstract class Itemcase class Article(desc: String, price: Double) extends Itemcase class Bundle(describe: String, discount: Double, item: Item*) extends Itemval arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001"))arr(Random.nextInt(arr.length)) match {  case SubmitTask(id, name) => {    println(s"$id, $name")  }  case HeartBeat(time) => {    println(time)  }  case CheckTimeOutTask => {    println("check")  }  //匹配类型  case Bundle(_, _, Article(_, _),_*) => {  }  //使用@将匹配的值赋给变量  art绑定第一个Article,其他的item赋值为rest  case Bundle(_, _, art @ Article(_, _), rest @ _*) => {  }  //art绑定第一个Article,再下一个赋值为rest  case Bundle(_, _, art @ Article(_, _), rest) => {  }}

Option

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

valm = Map("a" -> 1, "b" -> 2)var x:Int = 0m.get(x) match {  case Some(x) => println(x)  case None => println("key not exists...")  case _ => println("other...")}//Option的两个重要的方法//返回Some类型 没有返回空Noneobj.get("CHII") //没有返回默认值18,这个当没有初始值的时候很有用obj.getOrElse("HH", 18) 

这里写图片描述

val scores = Map(("CHII", 11), ("PLR", 12))//使用for推导式可以略过None值,如果get返回None将不会做任何处理(如下面不会打印出来)for (score <- scores.get("Chii")) println(score)//同样可以使用foreach map filter等方法略过None值scores.get("CHII").foreach(println _)

偏函数

//传入的类型为String,返回的是Intdef func1: PartialFunction[String, Int] = {case "one" => 1case "two" => 2case _ => -1}//调用func1("one")
0 0
原创粉丝点击