scala match
程序员文章站
2022-06-14 17:14:49
...
- 如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句
- 如果所有 case 都不匹配,又没有写 case _ 分支,那么会抛出 MatchError
- 每个 case 中,不用 break 语句,自动中断 case
- => 后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 括起来,也可以不括。
package com.xcu.chapter12
object demo01_match {
def main(args: Array[String]): Unit = {
val oper = '-'
val n1 = 20
val n2 = 10
var res = 0
oper match {
case '+' => res = n1 + n2
case '-' => res = n1 - n2
case '*' => res = n1 * n2
case '/' => res = n1 / n2
case _ => println("error")
}
println(res) // 10
}
}
- 模式匹配也可以有返回值
package com.xcu.chapter12
object demo02_MatchVar {
def main(args: Array[String]): Unit = {
val ch1 = '@'
//match 是一个表达式,因此可以有返回值
val res = ch1 match {
case '@' => ch1 + "laowang"
case _ => println("not match")
}
println(res) // @laowang
}
}
如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫
package com.xcu.chapter12
object demo01_match {
def main(args: Array[String]): Unit = {
for (ch <- "+-3ec") { // 是对"+-3!" 遍历
var dight = 0
ch match {
case '+' => println("+")
case '-' => println("-")
// 如果 case 后有条件守卫即if ,那么这时的 _ 不是表示默认匹配 是表示忽略传入的ch
case _ if ch.toString.equals("3") => dight = 3
case _ if (ch > 99) => {
printf("%s > 69\n", ch)
}
case _ => println("match error!")
}
}
}
}
如果在 case 关键字后跟变量名,那么 match 前表达式的值会赋给那个变量
package com.xcu.chapter12
object demo02_MatchVar {
def main(args: Array[String]): Unit = {
val ch = 'h'
ch match {
// 下面 case mychar 含义是 mychar = ch
case mychar => println(mychar + "ello")
case _ => println("not match!")
}
}
}
可以匹配对象的任意类型,这样做避免了使用 isInstanceOf 和 asInstanceOf 方法
package com.xcu.chapter12
object demo03_Match_Type {
def main(args: Array[String]): Unit = {
val a = 4
//说明 obj 实例的类型 根据 a 的值来返回
val obj = if (a == 1) 1
else if (a == 2) "2"
else if (a == 3) BigInt(3)
else if (a == 4) Map("aa" -> 1)
else if (a == 6) Array(1, 2, 3)
else if (a == 7) Array("aa", 1)
else if (a == 8) Array("aa")
//1. 根据 obj 的类型来匹配
val result = obj match {
case a: Int => a
case b: Map[String, Int] => "对象是一个字符串-数字的 Map 集合"
case d: Array[String] => d // "对象是一个字符串数组"
case e: Array[Int] => "对象是一个数字数组"
case f: BigInt => Int.MaxValue
case _ => "not amtch!"
}
println(result) // 对象是一个字符串-数字的 Map 集合
}
}
package com.xcu.chapter12
import scala.collection.mutable.ArrayBuffer
object demo04_Match_Arr {
def main(args: Array[String]): Unit = {
//给你一个数组集合,如果该数组时 Array(10,20) , 请使用默认匹配,返回 Array(20,10)
val arrs = Array(Array(1, 1, 0), Array(0, 1), Array(0))
for (arr <- arrs) {
val result = arr match {
case Array(0) => "0"
case Array(x, y) => ArrayBuffer(y, x)
case Array(1, _*) => "以1开头和数组"
case _ => "not match!"
}
println(result)
}
}
}
输出
以1开头和数组
ArrayBuffer(1, 0)
0
package com.xcu.chapter12
object demo05_list {
def main(args: Array[String]): Unit = {
for (list <- Array(List(7), List(1, 0), List(88), List(0, 0, 0), List(1, 0, 0))) {
val result = list match {
case 7 :: Nil => "7" // 匹配7
case x :: y :: Nil => y + " " + x // 匹配只有2个元素的列表
case 0 :: tail => "0 ..." // 匹配0开头的列表
case x :: Nil => x // 匹配只有1个元素的列表
case _ => "something else"
}
println(result)
}
}
}
输出
7
0 1
88
0 ...
something else
package com.xcu.chapter12
object demo06_MatchTuple {
def main(args: Array[String]): Unit = {
for (pair <- Array((0, 1), (1, 0), (10, 30), (1, 0, 2))) {
val result = pair match {
case (0, _) => "0 ..." // 匹配以0开头的元组
case (y, 0) => y // 匹配第二个元素为0的元组
case (x, y) => (y, x) // 匹配到只有2个元素的元组
case _ => "other"
}
println(result)
}
}
}
- case 中对象的 unapply 方法(对象提取器)返回 Some 集合则为匹配成功
- 返回 None 集合则为匹配失败
package com.xcu.chapter12
object demo07_MatchObject {
def main(args: Array[String]): Unit = {
// 模式匹配使用:
val number: Double = Square(6) // 36.0 //
number match {
//1. 当匹配到 case Square(n)
//2. 调用 object Square 的 unapply(z: Double),z 的值就是 number
//3. 如果对象提取器 unapply(z: Double) 返回的是 Some(6) ,则表示匹配成功,同时将6赋给 Square(n)的n
//4. 如果对象提取器 unapply(z: Double) 返回的是 None ,则表示匹配不成功
case Square(n) => println("匹配成功 n=" + n)
case _ => println("not match")
}
}
}
object Square {
//1. unapply 方法是对象提取器
//2. 接收 z:Double 类型
//3. 返回类型是 Option[Double]
//4. 返回的值是 Some(math.sqrt(z))即z的开平方的值,并放入到 Some(x)
def unapply(z: Double): Option[Double] = {
Some(math.sqrt(z))
None
}
def apply(z: Double): Double = z * z
}
package com.xcu.chapter12
object demo07_MatchObject {
def main(args: Array[String]): Unit = {
val wordString = "Alice,Bob,Thomas" //字符串
//说明
wordString match {
/* 当执行到 case Split_word(first, second, third)时
1.会调用 unapplySeq(str),把 "Alice,Bob,Thomas" 传入给unapplySeq的 str
2.如果unapplySeq返回的是 Some("Alice","Bob","Thomas"),
分别给 Split_word(first, second, third)
注意 这里的unapplySeq返回的值的个数需要和 Split_word(first, second, third)要一样
3.如果unapplySeq返回的 None ,表示匹配失败*/
case Split_word(first, second, third) => {
println(s"$first $second $third")
}
case _ => println("nothing matched")
}
}
}
object Split_word {
//当构造器是多个参数时,就会触发这个对象提取器
def unapplySeq(str: String): Option[Seq[String]] = {
if (str.contains(","))
Some(str.split(","))
else
None
}
}
下一篇: 反射获取类结构信息
推荐阅读
-
Spark新手入门——1.Scala环境准备
-
Scala当中什么是RDD(Resilient Distributed Datasets)弹性分布式数据集
-
Scala 孤立对象和单例对象方法体的用法和例子
-
python正则表达式match和search用法实例
-
PHP 正则匹配h1的数据报错 preg_match(): Unknown modifier 'h' in
-
mybatis_ The content of element type association must match (constructor,id,result,ass ociation,collection,discriminator)
-
win2003下PHP使用preg_match_all导致apache崩溃问题的解决方法
-
IndentationError: unindent does not match any outer indentation level笔记
-
POSIX 风格和兼容 Perl 风格两种正则表达式主要函数的类比(preg_match, preg_replace, ereg, ereg_replace)
-
mysql百万级全文索引及match快速查找