scala 的模式匹配,关键字是 match,相似于 java 的 switch,然而性能更弱小,咱们看看 scala 模式匹配的几种类型。
常量匹配
咱们这里以字符串为例。关键字是 match,case 前面通过 =>
来分隔匹配的模式以及匹配后的代码。
case 是各个分支,如果匹配胜利,就会执行相应的代码块,这里的代码块能够不必大括号。如果都不匹配,那旧执行 case _里的代码块,绝对于 java 的 default。
val str: String = "b"
val result = str match {
case "a" => 1
case "b" => println("b")
2
case "c" => 3
case _ => 0
}
println(result) // 2
如果 case b 局部改以下代码,因为 if 里的条件不合乎,那他会到 case _,返回 0。
case "b" if(str.equals("c")) => println("b")
类型匹配
与下面略微有点不同的是,类型后面要加一个参数,这个参数能够在前面的代码块里能够援用。
def main(args: Array[String]): Unit = {val array: Array[Any] = Array("a", 1, true, Array(1))
for (e <- array) {matchCase(e)
}
}
def matchCase(v: Any): Unit = {
v match {case a: Int => println(s"Int $a")
case b: String => println(s"String $b")
case c: Boolean => println(s"Boolean $c")
case _ => println(s"Nothing")
}
}
运行后果如下:
String a
Int 1
Boolean true
Nothing
数组匹配
def main(args: Array[String]): Unit = {val array: Array[Array[Int]] = Array(Array(1), Array(0, 1), Array(1, 2), Array(1, 2, 3), Array(2, 3, 4))
for (e <- array) {matchArray(e)
}
}
def matchArray(v: Array[Int]): Unit = {
v match {// 匹配 Array(1)
case Array(1) => println(v(0))
// 匹配两个长度的数组
case Array(x, y) => println("x+y=" + (x + y))
// 匹配第一个元素为 1,长度不限度的数组
case Array(1, _*) => println("x")
case _ => println(s"Nothing")
}
}
运行后果如下:
1
x+y=1
x+y=3
x
Nothing
元组匹配
def main(args: Array[String]): Unit = {val array: Array[Any] = Array((1, 2), (2, 1), (3, 4), (1, 2, 3))
for (e <- array) {matchTuple(e)
}
}
def matchTuple(v: Any): Unit = {
v match {
// 匹配 1 结尾
case (x, 1) => println(x)
// 匹配 1 结尾
case (1, y) => println(y)
// 匹配两个长度的元祖
case (x, y) => println(s"x = $x, y = $y")
case _ => println(s"Nothing")
}
}
运行后果如下:
2
2
x = 3, y = 4
Nothing
汇合匹配
上面正文掉的局部代码等同于他的下一句。
def main(args: Array[String]): Unit = {val list: List[List[Int]] = List(List(0), List(1), List(1, 2), List(1, 2, 3))
for (e <- list) {matchList(e)
}
}
def matchList(v: List[Int]): Unit = {
v match {// 匹配 List(1)
// case List(1) => println(v(0))
case 1 :: Nil => println(v(0))
// 匹配两个长度的数组
// case List(x, y) => println("x+y=" + (x + y))
case x :: y :: Nil => println("x+y=" + (x + y))
// 匹配第一个元素为 1,长度不限度的数组
// case List(1, _*) => println(v(0) + "-" + v.tail)
case x :: tail => println(x + "-" + tail)
case _ => println(s"Nothing")
}
运行后果如下:
0-List()
1
x+y=3
1-List(2, 3)
对象匹配
对象匹配是匹配对象的值,然而 case 里仅仅调用 Person 伴生对象的 apply 办法创立一个对象是不行的,他还须要 Person 的伴生对象申明 unapply 办法。
case 中比照的时候,他会把 Person 对象传入到 unapply 办法,失去 Some,而后再依据对象的属性进行匹配。
def main(args: Array[String]): Unit = {val list: List[Person] = List(Person("张三", 18), Person("李四", 20), Person("王五", 28))
for (e <- list) {matchPerson(e)
}
}
def matchPerson(v: Person): Unit = {
v match {case Person("张三", 18) => println(s"姓名:${v.name},年龄:${v.age}")
case Person("李四", 20) => println(s"姓名:${v.name},年龄:${v.age}")
case _ => println(s"Nothing")
}
}
class Person(val name: String, val age: Int) {
}
object Person {def apply(name: String, age: Int): Person = new Person(name, age)
def unapply(person: Person): Option[(String, Int)] = {if (null == person) {None} else {Some(person.name, person.age)
}
}
}
样例类
如果每次对象都要像下面进行匹配,那代码就很繁琐了。
所以 scala 提供了一个样例类,关键字 case,下面的代码能够简化成上面的:
def main(args: Array[String]): Unit = {val list: List[Person2] = List(Person2("张三", 18), Person2("李四", 20), Person2("王五", 28))
for (e <- list) {matchPerson(e)
}
}
def matchPerson(v: Person2): Unit = {
v match {case Person2("张三", 18) => println(s"姓名:${v.name},年龄:${v.age}")
case Person2("李四", 20) => println(s"姓名:${v.name},年龄:${v.age}")
case _ => println(s"Nothing")
}
}
case class Person2(name: String, age: Int)
通过 case 关键字,Person2 的对象就主动生成伴生对象,并且伴生对象除了生成下面的 apply 和 unapply 办法以外,还生成了 toString、equals、hashCode 和 copy 这些办法。如果作用在 class 上,那这个 class 就是多例的,如果作用在 object 上,那就是单例的。
咱们能够看到构造函数并没有指定 val 还是 var 的,他默认是 val 的。