第14章 模式匹配和样例类

样例类

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

在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,余数赋值给r
val (q,r) = BigInt(10) /% 3      

val Array(first, second, _*) = arr

for表达式中的模式

import scala.collection.JavaConversions.propertiesAsScalaMap
for ((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 = 0
m.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 CheckTimeOutTask
abstract class Item
case class Article(desc: String, price: Double) extends Item
case class Bundle(describe: String, discount: Double, item: Item*) extends Item

val 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 = 0
m.get(x) match {
  case Some(x) => println(x)
  case None => println("key not exists...")
  case _ => println("other...")
}



//Option的两个重要的方法

//返回Some类型 没有返回空None
obj.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,返回的是Int
def func1: PartialFunction[String, Int] = {
case "one" => 1
case "two" => 2
case _ => -1
}

//调用
func1("one")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>