基本语法
Scala模式匹配类似Java中的switch语法
var result = operator match {case '+' => a + bcase '-' => a -bcase _ => 'illegal'}
object Test {def main(args: Array[String]): Unit = {// 实现二元运算val a = 25val b = 13def matchDua(op: Char): Any = op match {case '+' => a+bcase _ => "非法运算符"}println(matchDua('+'))}}
- 如果所有都不匹配,那么会执行case 分支类似default。 如果没有case会抛出异常
- 每个case不需要break
- 可以匹配任何类型
=>后面的代码块,直到下一个case之前的代码作为一个整体执行,可以不用括号
模式守卫
如果想要匹配某个范围,可以增加条件守卫
object Test {def main(args: Array[String]): Unit = {def abs(x: Int) = x match {case i if i >= 0 => icase j if j < 0 => -jcase _ => "type illegal"}println(abs(-5))}}
模式匹配类型
匹配类型
object Test {def main(args: Array[String]): Unit = {// 匹配常量def describeConst(x: Any): String = x match {case 1 => "Num one"case "hello" => "String hello"case true => "Boolean true"case '+' => "Char +"case _ => "" // 表示什么都不做,_不是通配符,是占位符,写成 case abc => "" 也行}// 匹配类型def dsecribeType(x: Any): String = x match {case i: Int => "Int" + icase s: String => "String" + scase list: List[String] => "List" + listcase array: Array[Int] => "Array[Int]" + array.mkString(",")case a => "Something else: " + a // 如果兜底case还想返回类型,不用_形式(获取与当前值无关的返回)}val result = a match { //不需要用到具体的匹配项,可以用下划线代替case _: String => "String"case _: Int => "Int"case _ => "未匹配"}println(describeType(34))println(describeType("hello"))println(describeType(list("hi","hello")))println(describeType(list(2,3))) // 也匹配上了,泛型擦除,不会考虑泛型println(describeType(Array("hi","helli"))) // 数组比较底层,会考虑类型,不会泛型擦除println(describeType(Array(2, 23)))// 匹配数组for (arr <- List(Array(0),Array(1,0),Array(0,1,0),Array(1,1,0),Array("Hellp",23))) {val result = arr match {case Array(0) => "0"case Array(1,0) => "Array(1,0)"case Array(x, y) => "Array" + x + ", " + y // 匹配两元素数组case Array(0, _*) => "以0开头个数未知的数组"case Array(x, 1, z) => "中间为1的三元素数组"case _ => "something else"}}// 匹配列表for (list <- List(List(0), //0List(1,0), // List(x, y): 1, 0List(0,0,0), // List(0,...)List(1,1,0), // something elseList(88) // List(a): 88List("hello") //List(a): hello)) {val result = list match {case List(0) => "0" //case 0 :: Nil => ...case List(x, y) => "List(x, y): " + x + ", " + y //case x :: y :: Nil =>...case List(0, _x) => "List(0,...)" //case 0 :: tail => ...case List(a) => "List(a):" +acase _ => "something else"}println(result)}// 方式二val list = List(1,2,5,7)list match {case first :: second :: rest => println(s"firset: $first, second: $second, rest: $rest")// first: 1, second: 2, rest: List(5,7)case _ => println("something else")}// 匹配元组for (tuple <- List((0, 1),(0, 0),(0, 1, 0),(0, 1, 1),(1, 23, 56),("hello", true, 0.5))){val result = tuple match {case (a, b) => "" + a + ", " + "b"case (0, _) => "(0, _)"case (a, 1, _) => "(a, 1, _)" + acase _ => "something else"}}}}
元组的匹配
```scala // 在变量声明时匹配 val (x, y) = (10, “hello”) println(s”x: $x, y: $y”)
val List(first, second, _*) = List(23, 15, 9, 78) println(s”first: $first, second: $second”) //first: 23, second: 15 val fir :: sec :: rest = List(23,15,9,78) println(s”first: $fir, second: $sec, rest: $rest”)
// for推导式中进行模式匹配 val list: List[(String, Int)] = List((“a”, 12), (“b”, 35), (“c”, 27))
// 1.原本的遍历方式 for (elem <- list) { println(elem._1 + “ “ + elem._2) }
//2.将List元素直接定义为元组,对变量赋值 for((word, count) <- list) { println(word + “: “ + count) }
// 3.不考虑某个位置的变量,只遍历key或value for ((word, _) <- list) { println(word)//a b c }
// 4 可以指定某个位置的值必须是多少 for ((“a”, count) <- list){ println(count) // 12 }
<a name="CA0Pa"></a>#### 变量声明中的模式匹配```scaladef main(args: Array[String]): Unit = {val arr1 = (0 to 10).toArrayval Array(_, x, y, z, _*) = arr1 //模式匹配匹配第234个元素println(x, y, z)val list1 = (0 to 10).toListval List(a, b, _*) = list1 //匹配前两个val c :: d :: tail = list1 //匹配前两个
匹配对象
object Test {def main(args: Array[String]): Unit = {val student = new Student("alice", 18)// 针对对象实例匹配val result = student match {case new Student("alice", 18) => "Alice, 18"case _ => "else"}}}class Student(val name: String, val age: Int)object Student {def apply(name: String, age: Int): Student = new Student(name, age)// 必须实现一个unapply方法,用来对对象属性进行拆解def unapply(student: Student): Option[(String, Int)] = {if (student == null){None}else {Some((student.name, student.age))}}}
样例类
object Test {def main(args: Array[Strint]): Unit = {val student: Any = Student("alice", 18)val result = student match {case new Student("alice", 18) => "Alice, 18" //匹配具体内容case _ => "else"}println(result) // Alice 18val student2: Any = Student("jack",20)val result2 = student2 match {case Student(a,b) => println("匹配成功") //匹配类型case _ => println("未匹配")}}// 定义样例类// 对应的伴生对象、apply、unapply方法自动生成case class Student(name: String, age: Int) // 参数默认都是类的属性,不需要加val了
Option
避免空指针异常
- Some(x)表示实际值
- None表示没有值
```scala
def divede(a: Int, b: Int): Option[Int] = {
if (b == 0)
elseNone
}Some(a/b)
def main(args: Array[String]): Unit = { val result = divede(10, 0) match { case Some(x) => println(s”赏为:${x}”) case None => println(“出书不能为0”) }
// 方法二 println(result.getOrElse(“除数不能为0”)) }
<a name="J3KdA"></a>### 偏函数```scalaval pf: PartialFunction[Int, String] = { // Int参数类型,String返回类型case 1 => "yi"case 2 => "er"case _ => "wei pi pei"}println(pf(1)) // yi
object Test {def main(args: Array[String]): Unit = {val list: List[(String, Int)] = List(("a", 12), ("b", 35), ("c", 27))// 1. map 转换 ,实现key不变,value2倍val newList = list.map( tuple => (tuple._1, tuple._2 * 2))// 2. 用模式匹配对元组元素赋值val newList2 = list.map(tuple => {tuple match {case (word, count) => (word, count * 2)}})// 3. 省略lambda表达式val newList3 = list.map {case (word, count) => (word, count * 2)} // 偏函数}}
object Test{def main(args: Array[String]): Unit = {// 对输入数据分为不同的情形: 正、负、0val positiveAbs: PartialFunction[Int, Int] = {case x if x>0 => x}val negativeAbs: PartialFunction[Int, Int] = {case x if x < 0 => -x}val zeroAbs: PartialFunction[Int, Int] = {case 0 => 0}def abs(x: Int): Int = (positiveAbs orElse negativeAbs orElse zeroAbs) (x)println(abs(-67)) //67}}
提取器
指的就是unapply方法
样例类自动实现了unapply
class Student(var name: String, var age: Int)object Student {// apply根据给定的字段,封装成Student类型对象def apply(name: String, age: Int) = new Student(name, age)// unapply根据传入的学生对象获取属性def unapply(s: Student) = {if(s == null)NoneelseSome(s.name, s.age)}}def main(args: Array[String]):Unit = {val s1 = new Student("张三", 23)val s2 = Student("李四", 24)//方式一println(s1.name,s1.age)//方式二val result = Student.unapply(s1)println(result)//方式三 如果没有unapply方法,会报错,必须有提取器s1 match {case Student(name, age) => println(s"${name}, ${age}")case _ => println("未匹配")}}
