【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)