1、匹配模式
Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句、类型检查等。
并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配
1、匹配字符串
/**
* 匹配模式(match的使用):字符串匹配
* Created by 12706 on 2017/11/27.
*/
class MatchDemo {
val arr = Array("a","b","c")
val index = arr(Random.nextInt(arr.length))
//字符串匹配 使用matct
index match {
case "a" => play("魔法少女小圆")
case "b" => play("妖精的旋律")
case "c" => play("命运石之门")
case _ => println("随机播放")//相当于java的switch中default
}
def play(name : String): Unit ={
println("动漫:" + name)
}
}
object MatchDemo {
def main(args: Array[String]): Unit = {
val m = new MatchDemo
}
}
执行多次能看到输出
动漫:命运石之门,动漫:魔法少女小圆,动漫:妖精的旋律
2、类型匹配
class MatchDemo2 {
val arr = Array(18,"scala",3.14)
val index = arr(Random.nextInt(3))
//进行类型匹配,case y: Double if(y >= 0) => ...
index match {
//模式匹配的时候还可以添加守卫条件。如不符合守卫条件,将掉入case _中
case i : Int if (i > 15) => println("得到了个整型:" + i)
case d : Double => println("得到了个浮点类型:" + d)
case s : String => println("得到了个字符串类型:" + s)
case _ => println("不知道得了什么类型")
}
}
object MatchDemo2 {
def main(args: Array[String]): Unit = {
val m = new MatchDemo2
}
}
输出(只列一个)
得到了个浮点类型:3.14
3、匹配数字,List和元祖
class MatchDemo3 {
val arr = Array (1,3,6)
//匹配数组
arr match {
//匹配三个数,第一个是1,后两个任意,匹配时arr中3,6的值会赋给x,y
case Array(1,x,y) => println("arr case1:" + (x + y))
case Array(2,3,x) => println("arr case2:" + x)
//这个也是能匹配到的,但是第一个已经匹配了就不再匹配后续
case Array(1,_*) => throw new Exception("arr case3 匹配不到了")
}
val list = List (2,3,7)
//匹配list
list match {
//可以使用匹配数组的方式
// case List(2,3,6) => println("arr case1:" + 236)
// case List(2,x,y) => println("arr case1:" + (x + y))
//头是2,后面为空
case 2 :: Nil => println("只有2")
//只有两个元素
case 2 :: 3 :: Nil => println("只有2 3 ")
//这种输出形式一定要写s
case 2 :: x :: _ => println(s"x:$x ")
case 2 :: 3 :: x => println("list:" + x(0))
case _ => println("else")
}
val tup = (2, 3, 7)
//匹配元祖
tup match {
case (2, x, y) => println(s"2, $x, $y")
case (_, z, 7) => println(z)
case _ => println("else")
}
}
object MatchDemo3 {
def main(args: Array[String]): Unit = {
val m = new MatchDemo3
}
}
输出
arr case1:9
x:3
2, 3, 7
注意:在Scala中列表要么为空(Nil表示空列表)要么是一个head元素加上一个tail列表。
9 :: List(5, 2) :: 操作符是将给定的头和尾创建一个新的列表
注意::: 操作符是右结合的,如9 :: 5 :: 2 :: Nil相当于 9 :: (5 :: (2 :: Nil))
2、样例类
在Scala中样例类是一中特殊的类,可用于模式匹配。case class是多例的,后面要跟构造参数,case object是单例的
/**
* 样例类
* 开头声明三个样例类,case class是多例的,需要传入参数
* case object是单例的不能传入参数
* Created by 12706 on 2017/11/27.
*/
case class MySubmitTask(id : Int, name : String)
case class SucceedTask(info : String)
case object TimeOutTask
class MatchDemo4 {
//样例类可new可不new
val arr = Array(new MySubmitTask(1,"wordcount"),SucceedTask("任务提交成功"),TimeOutTask)
var task = arr (Random.nextInt(3))
//样例类匹配
task match {
case MySubmitTask(id,name) => println(s"MySubmitTask($id,$name)")
case SucceedTask(name) => println(s"SucceedTask($name)")
case TimeOutTask =>println("超时")
}
}
object MatchDemo4 {
def main(args: Array[String]): Unit = {
val m = new MatchDemo4
}
}
输出有三种
超时,SucceedTask(任务提交成功),MySubmitTask(1,wordcount)
3、Option类型
在Scala中Option类型样例类用来表示可能存在或也可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值
class OptionDemo {
val map = Map (("a",18),("b",81))
//get()的返回就是Option,而Option有两种实现一种是case class另一种是case object对应Some(i)和None
val a = map.get("a")
println(a)
val c = map.get("c")
println(c)
// val c2 = map("c")这种方式是会直接抛出异常的NoSuchElementException
val b = map.get("b") match {
case Some(x) => println(x)
case None => println("元素不存在")
}
}
object OptionDemo {
def main(args: Array[String]): Unit = {
val option = new OptionDemo
//对于找不到的元素赋默认值的方法,getOrElse找不到c对应的值那么返回默认值0
val c = option.map.getOrElse("c",0)
println(c)
}
}
输出
Some(18)
None
81
0
4、偏函数
被包在花括号内没有match的一组case语句是一个偏函数,它是PartialFunction[A, B]的一个实例,A代表参数类型,B代表返回类型,常用作输入模式匹配
class PartialFunctionDemo {
//String是参数类型,Int是返回类型
def parFunc : PartialFunction[String, Int] = {
case "one" => {
print("partial函数")
1
}
case "two" => {
print("partial函数")
2
}
case _ => -1
}
def func(str : String): Int = str match {
case "one" => {
print("func函数")
1
}
case "two" => {
print("func函数")
2
}
case _ => -1
}
}
object PartialFunctionDemo {
def main(args: Array[String]): Unit = {
val pd = new PartialFunctionDemo
println(pd.parFunc("one"))
println(pd.func("two"))
}
}
输出
partial函数1
func函数2
https://blog.csdn.net/bitcarmanlee/article/details/76736252
https://www.jianshu.com/p/8b5892060858
https://my.oschina.net/u/2000675/blog/1592140