Scala's pattern matching, the keyword is match, similar to java's switch, but with more powerful functions, let's look at several types of scala pattern matching.

Constant matching

Let's take a string as an example here. The keyword is match, and the case is followed by => to separate the matched pattern and the matched code.
The case is each branch. If the match is successful, the corresponding code block will be executed. The code block here can be used without braces. If they do not match, the code block in case _ is executed, which is relative to java's 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

If the following code is changed in the case b part, because the condition in the if is not met, it will go to case _ and return 0.

case "b" if(str.equals("c"))  => println("b")

Type match

A little bit different from the above is that a parameter is added in front of the type, and this parameter can be referenced in the following code block.

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")
    }
}

The results of the operation are as follows:

String a
Int 1
Boolean true
Nothing

Array matching

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")
    }
}

The results of the operation are as follows:

1
x+y=1
x+y=3
x
Nothing

Tuple matching

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")
    }
}

The results of the operation are as follows:

2
2
x = 3, y = 4
Nothing

Set match

The part of the code commented out below is equivalent to his next sentence.

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")
}

The results of the operation are as follows:

0-List()
1
x+y=3
1-List(2, 3)

Object matching

Object matching is the value of the matching object, but in the case, it is not enough to just call the apply method of the Person companion object to create an object. He also needs the Person companion object to declare the unapply method.
When comparing in the case, he will pass the Person object to the unapply method, get Some, and then match according to the properties of the object.

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

Sample class

If every time the object has to be matched as above, the code is very cumbersome.
So scala provides a sample class, keyword case, the above code can be simplified to the following:

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)

Through the case keyword, the Person2 object automatically generates a companion object, and in addition to the above apply and unapply methods, the companion object also generates the toString, equals, hashCode, and copy methods. If it acts on a class, then this class is multiple cases, if it acts on an object, it is singleton.
We can see that the constructor does not specify val or var, it defaults to val.


大军
847 声望183 粉丝

学而不思则罔,思而不学则殆


« 上一篇
Scala - 映射

引用和评论

0 条评论