【Scala】08 模式匹配 Match Case

 

由Scala封装的一套match case处理,功能比原Java的更为强大

package cn

import scala.collection.immutable.IndexedSeqDefaults.defaultApplyPreferredMaxLength.>=
import scala.collection.immutable.Queue
import scala.collection.mutable

object HelloScala {
  def main(args: Array[String]): Unit = {
    // - - - - -  模式匹配 matchCase - - - - -

    val a = 2
    val b = a match {
      case 1 => "one"
      case 2 => "one"
      case 3 => "one"
      case 4 => "one"
      case _ => "other"
    }
    b(a)

    // - - - - - 实现二元运算 - - - - -
    val x = 22
    val y = 33

    def matchDualOp(op : Char) = op match {
      case '+' => x + y
      case '-' => x - y
      case '*' => x * y
      case '/' => x / y
      case _ => "uncaught op"
    }

    println(matchDualOp('*'))
    println(matchDualOp('&'))

    // - - - - - 模式守卫 求整数的绝对值 - - - - -
    def abs(num : Int) : Int = {
      num match {
        case i if i >= -1 => i
        case i if i < 0 =>  -i
      }
    }

    // - - - - - 模式匹配常量 - - - - -
    def descConst(o : Any) : String = o match {
      case  1 => "Num ONE"
      case  "HELLO" => "String HELLO"
      case  true => "Boolean True"
      case  '+' => "Char +"
      case _ => "don't know val what it is "
    }

    // 模式匹配类型
    def descType(x : Any) : String = x match {
      case i : Int => "Int " + i
      case s : String => "String " + s
      case l : List[String] => "List[String] " + l
      case ss => "Other Type, But is scala.Any " + ss.getClass
    }

    // - - - - - 模式匹配,匹配数组处理 - - - - -
    for(array <- List(
      Array(0),
      Array(1,0),
      Array(0,1,0),
      Array(1,1,0),
      Array(2,3,7,15),
      Array("hello", 10,7,15)
    )) {
      val res = array match {
        case Array(0) => "0"
        case Array(1, 0) => "Array(1, 0)"
        case Array(x, y) => s"Array($x, $y)" // 匹配两元素的数组
        case Array(0, _*) => "First Element is 0" // 匹配开头为0的数组
        case Array(x, 1, y) => "0" // 匹配中间为1的三元素数组
        case _ => "Something else" // 其他
      }
      println(res)
    }

    // - - - - - 匹配列表 - - - - -
    for(list <- List(
      List(1,0),
      List(1,0,1),
      List(0,0,0),
      List(1,1,0),
      List(88),
    )) {
      val result = list match {
        case List(0) => "0"
        case List(x, y) => s"List($x, $y)"
        case List(0, _*) => list.toString() // 要求以0开头的List
        case List(a) => s"List($a)" // 只有一个元素的List
        case _ => "Something else"
      }
      println(result)
    }

    // - - - - - 方式 - - - - -
    val list = List(1, 2, 5, 7, 24)

    list match {
      case first :: second :: reset => {
        // first = 1, second = 2, reset = List(5, 7, 24)
        println(s" first = $first, second = $second, reset = $reset")
      }
      case _ => println("Something else")
    }

    // 匹配元组
    for(tuple <- List(
      (0,1),
      (0,0),
      (0),
      (1),
      (0,1,1),
      (1, 23,56),
      ("hello", true, 0.5),
    )) {
      val result = tuple match {
        case (a, b) => s"tuple($a, $b)"
        case (0, _) => s"tuple(0, _)"
        case (a, 1, 0) => "(a, 1, _)"
        case (x, y, z) => s"($x, $y, $z)"
        case _ => "something else"
      }
      println(result)
    }

  }
}

 

对变量进行模式匹配和类型 推导

package cn

import scala.collection.immutable.IndexedSeqDefaults.defaultApplyPreferredMaxLength.>=
import scala.collection.immutable.Queue
import scala.collection.mutable

object HelloScala {
  def main(args: Array[String]): Unit = {
    // 变量声明匹配处理
    val (x, y) = (10, "string")
    println(x)

    val List(a, b, _*) = List(1, 3, 4, 8, 33)

    val valA :: valB :: others = List(1, 3, 4, 8, 33)

    // 类似 JS的反向赋值,这些声明的集合的变量都可以被访问调用

    val list2 = List(
      ("a", 88),
      ("b", 188),
      ("c", 288),
      ("d", 388),
      ("e", 488),
    )
    // For循环的迭代对象 类型推导
    for( (key, value) <- list2) {
      println(s"($key, $value)") // 可以直接获取
    }

    // 或者按缺省参数处理 只获取其中的一个
    for( (key, _) <- list2) {
      println(s"($key)") // 可以直接获取
    }

    // 或者用于具体匹配
    for( ("a", ccc) <- list2) {
      println(s"($ccc)") // 可以直接获取
    }

  }
}

自定义对象的模式匹配:

package cn

object HelloScala {
  def main(args: Array[String]): Unit = {
    // 对象匹配&样例类
    val student = new Student("alice", 19)

    val res = student match {
      case Student("alice", 19) => "Alice, 19"
      case _ => "Else"
    }

    println(res)
  }
}

class Student(val name : String, val age : Int)
// 需要伴生对象支持
object Student {
  def apply(name : String, age : Int) : Student = new Student(name, age)

  /**
   * 使用对象匹配需要这个unapply方法来支持
   * @param student
   * @return
   */
  def unapply(student: Student) : Option[(String, Int)] = {
    if (null == student) None
    else Some( (student.name, student.age))
  }
}

样例类就是把上面的内容做好了封装处理,只需要case前缀声明一下类

package cn

object HelloScala {
  def main(args: Array[String]): Unit = {
    // 对象匹配&样例类
    val student = new Student("alice", 19)

    val res = student match {
      case Student("alice", 19) => "Alice, 19"
      case _ => "Else"
    }

    println(res)
  }
}

// 样例类已经封装好处理,声明完成即可直接用来模式匹配
case class Student(val name : String, val age : Int)

 

posted @ 2021-07-19 14:50  emdzz  阅读(105)  评论(0编辑  收藏  举报