Scala_模式匹配
Posted lishanstudy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala_模式匹配相关的知识,希望对你有一定的参考价值。
一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
1.
package scalaprogram.May07 import scala.util.Random //模式匹配 ---------- 升级版的switch语句 object PatternTest { def main(args: Array[String]): Unit = { //1、字符匹配 val charStr = ‘-‘ charStr match { case ‘+‘ => println("匹配上了加号") case ‘-‘ => println("匹配上了减号") case ‘*‘ => println("匹配上了乘号") case ‘/‘ => println("匹配上了除号") //注意。所有的模式匹配都必须最终匹配上一个值,如果没有匹配上任何值,就会报错 case _ => println("都没有匹配上,我是默认值") } //2、 匹配字符串 val arr = Array("hadoop", "zookeeper", "spark") val name = arr(Random.nextInt(arr.length))//随机获取arr数组中的一个字符串 name match { case "hadoop" => println("大数据分布式存储和计算框架...") case "zookeeper" => println("大数据分布式协调服务框架...") case "spark" => println("大数据分布式内存计算框架...") case _ => println("我不认识你...") } //3、守卫 guard var ch = "500" var sign = 0 ch match { case "+" => sign = 1 case "-" => sign = 2 case _ if ch.equals("500") => sign = 3 //可以加一个过滤条件 case _ => sign = 4 } println(ch + " " + sign) //4、 匹配类型 //注意泛型擦除,在模式匹配当中的类型匹配中,除了Array类型以外,所有的其他的数据类型都会被擦除掉 val a = 3 val obj = if(a == 1) 1 else if(a == 2) "2" else if(a == 3) BigInt(3) else if(a == 4) Map("aa" -> 1) //键值对 键:aa 值:1 else if(a == 5) Map(1 -> "aa") else if(a == 6) Array(1, 2, 3) else if(a == 7) Array("aa", 1) else if(a == 8) Array("aa") val r1 = obj match { case x: Int => x case s: String => s.toInt case BigInt => -1 //不能这么匹配 前面必须为一个变量 (泛型擦除) case _: BigInt => Int.MaxValue case m: Map[String, Int] => "Map[String, Int]类型的Map集合" case m: Map[_, _] => "Map集合" case a: Array[Int] => "It‘s an Array[Int]" case a: Array[String] => "It‘s an Array[String]" case a: Array[_] => "It‘s an array of something other than Int" case _ => 0 } println(r1 + ", " + r1.getClass.getName) //5、匹配数组、元组、集合 val arr1 = Array(1, 3) arr1 match { case Array(0, x, y) => println(x + " " + y) case Array(0) => println("only 0") //匹配数组以1 开始作为第一个元素 case Array(1, _*) => println("0 ...") case _ => println("something else") } val lst = List(0, 3, -1) lst match { case 0 :: Nil => println("only 0") // List(0) 即Nil是空List 双冒号是追加进入 case x :: y :: Nil => println(s"x: $x y: $y") //List(x,y) case 0 :: tail => println("0 ...") //tail任意值 case _ => println("something else") } val tup = (1, 3, 7) tup match { case (1, x, y) => println(s"1, $x , $y") case (_, z, 5) => println(z) case _ => println("else") } } }
运行结果:
匹配上了减号 大数据分布式存储和计算框架... 500 3 2147483647, java.lang.Integer 0 ... 0 ... 1, 3 , 7
2.apply与unapply
package scalaprogram.May07 /** * apply方法通常称为注入方法,在伴生对象中做一些初始化操作 * apply方法的参数列表不需要和构造器的参数列表统一 * unapply方法通常称为提取方法,使用unapply方法提取固定数量的参数来进行模式匹配 * unapply方法会返回一个序列(Option),内部产生一个Some对象,Some对象存放一些值 * apply方法和unapply方法会被隐式的调用 */ object Apply_unapply { def main(args: Array[String]): Unit = { val currency = Currency(30.2, "EUR") //没有使用new 调用了Currency的apply方法 println("&&&&&&&&&&&&&&&&&&&&&&") currency match { //隐式调用了unapply方法,提取若干个参数进行模式匹配 case Currency(amount, "USD") => println("USD:" + amount) //case Currency(amount, "EUR") => println("EUR:" + amount) case _ => println("No match.") } } } class Currency(val value: Double, val unit: String) {} object Currency{ def apply(value: Double, unit: String): Currency = { println("apply()") new Currency(value, unit) } def unapply(currency: Currency): Option[(Double,String)] = { println("unapply()") if (currency == null){ None } else{ Some(currency.value, currency.unit) } } }
运行结果:
apply() &&&&&&&&&&&&&&&&&&&&&& unapply() No match.
package scalaprogram.May07 object Test { def main(args: Array[String]) { println ("Apply 方法 : " + apply("Zara", "gmail.com")); println ("Apply 方法 : " + Test("Zara", "gmail.com")); //通过类调用test的apply(user: String, domain: String)方法 println ("Unapply 方法 : " + unapply("Zara@gmail.com")); //显式调用unapply方法 println ("Unapply 方法 : " + unapply("Zara Ali")); val x = Test(5) println(x) x match { case Test(num) => println(x + " 是 " + num + " 的两倍!") //case class //unapply 被调用 (隐式调用) case _ => println("无法计算") } } def apply(x:Int): Int = {x * 2} def unapply(z: Int): Option[Int] = { println("unapply") if (z%2 == 0) Some(z/2) else None } // 注入方法 (可选) def apply(user: String, domain: String) = {user +"@"+ domain} // 提取方法(必选) def unapply(str: String): Option[(String, String)] = { val parts = str split "@" if (parts.length == 2){ Some(parts(0), parts(1)) }else{ None } } }
运行结果:
Apply 方法 : Zara@gmail.com Apply 方法 : Zara@gmail.com Unapply 方法 : Some((Zara,gmail.com)) Unapply 方法 : None 10 unapply 10 是 5 的两倍!
以上是关于Scala_模式匹配的主要内容,如果未能解决你的问题,请参考以下文章