基本语法

Scala模式匹配类似Java中的switch语法

  1. var result = operator match {
  2. case '+' => a + b
  3. case '-' => a -b
  4. case _ => 'illegal'
  5. }
  1. object Test {
  2. def main(args: Array[String]): Unit = {
  3. // 实现二元运算
  4. val a = 25
  5. val b = 13
  6. def matchDua(op: Char): Any = op match {
  7. case '+' => a+b
  8. case _ => "非法运算符"
  9. }
  10. println(matchDua('+'))
  11. }
  12. }
  1. 如果所有都不匹配,那么会执行case 分支类似default。 如果没有case会抛出异常
  2. 每个case不需要break
  3. 可以匹配任何类型
  4. =>后面的代码块,直到下一个case之前的代码作为一个整体执行,可以不用括号

    模式守卫

    如果想要匹配某个范围,可以增加条件守卫

    1. object Test {
    2. def main(args: Array[String]): Unit = {
    3. def abs(x: Int) = x match {
    4. case i if i >= 0 => i
    5. case j if j < 0 => -j
    6. case _ => "type illegal"
    7. }
    8. println(abs(-5))
    9. }
    10. }

    模式匹配类型

    匹配类型

    1. object Test {
    2. def main(args: Array[String]): Unit = {
    3. // 匹配常量
    4. def describeConst(x: Any): String = x match {
    5. case 1 => "Num one"
    6. case "hello" => "String hello"
    7. case true => "Boolean true"
    8. case '+' => "Char +"
    9. case _ => "" // 表示什么都不做,_不是通配符,是占位符,写成 case abc => "" 也行
    10. }
    11. // 匹配类型
    12. def dsecribeType(x: Any): String = x match {
    13. case i: Int => "Int" + i
    14. case s: String => "String" + s
    15. case list: List[String] => "List" + list
    16. case array: Array[Int] => "Array[Int]" + array.mkString(",")
    17. case a => "Something else: " + a // 如果兜底case还想返回类型,不用_形式(获取与当前值无关的返回)
    18. }
    19. val result = a match { //不需要用到具体的匹配项,可以用下划线代替
    20. case _: String => "String"
    21. case _: Int => "Int"
    22. case _ => "未匹配"
    23. }
    24. println(describeType(34))
    25. println(describeType("hello"))
    26. println(describeType(list("hi""hello")))
    27. println(describeType(list(2,3))) // 也匹配上了,泛型擦除,不会考虑泛型
    28. println(describeType(Array("hi","helli"))) // 数组比较底层,会考虑类型,不会泛型擦除
    29. println(describeType(Array(2, 23)))
    30. // 匹配数组
    31. for (arr <- List(
    32. Array(0),
    33. Array(1,0),
    34. Array(0,1,0),
    35. Array(1,1,0),
    36. Array("Hellp",23)
    37. )) {
    38. val result = arr match {
    39. case Array(0) => "0"
    40. case Array(1,0) => "Array(1,0)"
    41. case Array(x, y) => "Array" + x + ", " + y // 匹配两元素数组
    42. case Array(0, _*) => "以0开头个数未知的数组"
    43. case Array(x, 1, z) => "中间为1的三元素数组"
    44. case _ => "something else"
    45. }
    46. }
    47. // 匹配列表
    48. for (list <- List(
    49. List(0), //0
    50. List(1,0), // List(x, y): 1, 0
    51. List(0,0,0), // List(0,...)
    52. List(1,1,0), // something else
    53. List(88) // List(a): 88
    54. List("hello") //List(a): hello
    55. )) {
    56. val result = list match {
    57. case List(0) => "0" //case 0 :: Nil => ...
    58. case List(x, y) => "List(x, y): " + x + ", " + y //case x :: y :: Nil =>...
    59. case List(0, _x) => "List(0,...)" //case 0 :: tail => ...
    60. case List(a) => "List(a):" +a
    61. case _ => "something else"
    62. }
    63. println(result)
    64. }
    65. // 方式二
    66. val list = List(1,2,5,7)
    67. list match {
    68. case first :: second :: rest => println(s"firset: $first, second: $second, rest: $rest")
    69. // first: 1, second: 2, rest: List(5,7)
    70. case _ => println("something else")
    71. }
    72. // 匹配元组
    73. for (tuple <- List(
    74. (0, 1),
    75. (0, 0),
    76. (0, 1, 0),
    77. (0, 1, 1),
    78. (1, 23, 56),
    79. ("hello", true, 0.5)
    80. )){
    81. val result = tuple match {
    82. case (a, b) => "" + a + ", " + "b"
    83. case (0, _) => "(0, _)"
    84. case (a, 1, _) => "(a, 1, _)" + a
    85. case _ => "something else"
    86. }
    87. }
    88. }
    89. }

    元组的匹配

    ```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 }

  1. <a name="CA0Pa"></a>
  2. #### 变量声明中的模式匹配
  3. ```scala
  4. def main(args: Array[String]): Unit = {
  5. val arr1 = (0 to 10).toArray
  6. val Array(_, x, y, z, _*) = arr1 //模式匹配匹配第234个元素
  7. println(x, y, z)
  8. val list1 = (0 to 10).toList
  9. val List(a, b, _*) = list1 //匹配前两个
  10. val c :: d :: tail = list1 //匹配前两个

匹配对象

  1. object Test {
  2. def main(args: Array[String]): Unit = {
  3. val student = new Student("alice", 18)
  4. // 针对对象实例匹配
  5. val result = student match {
  6. case new Student("alice", 18) => "Alice, 18"
  7. case _ => "else"
  8. }
  9. }
  10. }
  11. class Student(val name: String, val age: Int)
  12. object Student {
  13. def apply(name: String, age: Int): Student = new Student(name, age)
  14. // 必须实现一个unapply方法,用来对对象属性进行拆解
  15. def unapply(student: Student): Option[(String, Int)] = {
  16. if (student == null){
  17. None
  18. }else {
  19. Some((student.name, student.age))
  20. }
  21. }
  22. }

样例类

  1. object Test {
  2. def main(args: Array[Strint]): Unit = {
  3. val student: Any = Student("alice", 18)
  4. val result = student match {
  5. case new Student("alice", 18) => "Alice, 18" //匹配具体内容
  6. case _ => "else"
  7. }
  8. println(result) // Alice 18
  9. val student2: Any = Student("jack",20)
  10. val result2 = student2 match {
  11. case Student(a,b) => println("匹配成功") //匹配类型
  12. case _ => println("未匹配")
  13. }
  14. }
  15. // 定义样例类
  16. // 对应的伴生对象、apply、unapply方法自动生成
  17. case class Student(name: String, age: Int) // 参数默认都是类的属性,不需要加val了

Option

避免空指针异常

  • Some(x)表示实际值
  • None表示没有值 ```scala def divede(a: Int, b: Int): Option[Int] = { if (b == 0)
    1. None
    else
    1. 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”)) }

  1. <a name="J3KdA"></a>
  2. ### 偏函数
  3. ```scala
  4. val pf: PartialFunction[Int, String] = { // Int参数类型,String返回类型
  5. case 1 => "yi"
  6. case 2 => "er"
  7. case _ => "wei pi pei"
  8. }
  9. println(pf(1)) // yi
  1. object Test {
  2. def main(args: Array[String]): Unit = {
  3. val list: List[(String, Int)] = List(("a", 12), ("b", 35), ("c", 27))
  4. // 1. map 转换 ,实现key不变,value2倍
  5. val newList = list.map( tuple => (tuple._1, tuple._2 * 2))
  6. // 2. 用模式匹配对元组元素赋值
  7. val newList2 = list.map(
  8. tuple => {
  9. tuple match {
  10. case (word, count) => (word, count * 2)
  11. }
  12. }
  13. )
  14. // 3. 省略lambda表达式
  15. val newList3 = list.map {
  16. case (word, count) => (word, count * 2)
  17. } // 偏函数
  18. }
  19. }
  1. object Test{
  2. def main(args: Array[String]): Unit = {
  3. // 对输入数据分为不同的情形: 正、负、0
  4. val positiveAbs: PartialFunction[Int, Int] = {
  5. case x if x>0 => x
  6. }
  7. val negativeAbs: PartialFunction[Int, Int] = {
  8. case x if x < 0 => -x
  9. }
  10. val zeroAbs: PartialFunction[Int, Int] = {
  11. case 0 => 0
  12. }
  13. def abs(x: Int): Int = (positiveAbs orElse negativeAbs orElse zeroAbs) (x)
  14. println(abs(-67)) //67
  15. }
  16. }

提取器

指的就是unapply方法
样例类自动实现了unapply

  1. class Student(var name: String, var age: Int)
  2. object Student {
  3. // apply根据给定的字段,封装成Student类型对象
  4. def apply(name: String, age: Int) = new Student(name, age)
  5. // unapply根据传入的学生对象获取属性
  6. def unapply(s: Student) = {
  7. if(s == null)
  8. None
  9. else
  10. Some(s.name, s.age)
  11. }
  12. }
  13. def main(args: Array[String]):Unit = {
  14. val s1 = new Student("张三", 23)
  15. val s2 = Student("李四", 24)
  16. //方式一
  17. println(s1.name,s1.age)
  18. //方式二
  19. val result = Student.unapply(s1)
  20. println(result)
  21. //方式三 如果没有unapply方法,会报错,必须有提取器
  22. s1 match {
  23. case Student(name, age) => println(s"${name}, ${age}")
  24. case _ => println("未匹配")
  25. }
  26. }