scala pattern matching

scala语言的一大重要特性之一就是模式匹配。在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中,只能是用在函数体类的,且需要结合break使用。但是,在scala语言中,pattern matching除了有case关键字,其他,似乎和java又有很多甚至完全不同的东西。

scala在消息处理中为模式匹配提供了强大的支持!

下面看看模式匹配的英文定义:

A pattern match includes a sequence of alternatives, each starting with the keyword case. Each alternative includes a pattern and one or more expressions, which will be evaluated if the pattern matches. An arrow symbol => separates the pattern from the expressions. 

再来给个简单的例子吧:

 1 package lession3
 2 
 3 object MyPattern {
 4    def main(args: Array[String]) {
 5       println(matchTest(3))
 6 
 7    }
 8    def matchTest(x: Int): String = x match {
 9       case 1 => "one"
10       case 2 => "two"
11       case _ => "many"
12    }
13 }

上面的例子,case部分,是不是很像java中switch语句中的case?下面给个对应的简单的java例子:

 1 package com.shihuc.java;
 2 
 3 public class MySwitch {
 4     public static void main(String args[]){
 5         System.out.println(matchTest(3));
 6     }
 7     
 8     public static String matchTest(int x){
 9         String ret = "";
10         switch(x){
11         case 1: 
12             ret = "one";
13             break;
14         case 2:
15             ret = "two";
16             break;
17         default:
18             ret = "many";
19             break;
20         }
21         return ret;
22     }
23 }

呵呵,是不是发现了相识和差异?都是一个模式对应一系列的候选可能表达(expressions,其实,就是一系列的处理过程),scala里面的case语句没有java switch中的break,scala里面的下划线_对应于java switch中的default,还有,是不是觉得那个x match很像java代码中的switch(x),当然了,学习一种语言,可以这么类比着学习!至少我是这么学的!

另外,java的switch语句中的x是数值类型(int或者enum)的参数,但是,scala中,是没有这么要求的!任意类型都可以,这个是不是很强大?

 1 object Test {
 2    def main(args: Array[String]) {
 3       println(matchTest("two"))
 4       println(matchTest("test"))
 5       println(matchTest(1))
 6 
 7    }
 8    def matchTest(x: Any): Any = x match {
 9       case 1 => "one"
10       case "two" => 2
11       case y: Int => "scala.Int"
12       case _ => "many"
13    }
14 }

还有,scala的模式匹配书写格式,还可以如下这样:

 1 object Test {
 2    def main(args: Array[String]) {
 3       println(matchTest("two"))
 4       println(matchTest("test"))
 5       println(matchTest(1))
 6 
 7    }
 8    def matchTest(x: Any){
 9       x match {          //此处的x match关键部分,不再写在函数名称后面了,而是写在了函数体里面,即在函数块{}括号里面!
10          case 1 => "one"
11          case "two" => 2
12          case y: Int => "scala.Int"
13          case _ => "many"
14       }
15    }
16 }

再者,scala还支持模式匹配类,即在正常class定义中加入关键字case, 看下面的例子:

 1 object Test {
 2    def main(args: Array[String]) {
 3        val alice = new Person("Alice", 25)
 4        val bob = new Person("Bob", 32)
 5        val charlie = new Person("Charlie", 32)
 6    
 7       for (person <- List(alice, bob, charlie)) {
 8          person match {
 9             case Person("Alice", 25) => println("Hi Alice!")
10             case Person("Bob", 32) => println("Hi Bob!")
11             case Person(name, age) =>
12                println("Age: " + age + " year, name: " + name + "?")
13          }
14       }
15    }
16    // case class, empty one.
17    case class Person(name: String, age: Int)
18 }

case关键字将会促使scala编译器为Person类自动加入一些模式匹配的特性。

首先,自动将Person类的参数类型转换为不可变(immutable)类型(即val,注意,val是可选的,此时);若想用可变的参数,则需要显示表明参数类型为var。

其次,编译器自动将为Person类添加了例如equalshashCode,以及toString等class方法,我们不需要自己再写相关的方法了。

scala的异常处理,也会涉及到case的使用,即各种细分的异常的模式匹配。这个与java中的try/catch()之多个catch()体不同:

JAVA try catch:

 1 package com.shihuc.java;
 2 
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.IOException;
 6 
 7 public class FileOpen2 {
 8 
 9     public static void main(String args[]){
10         try {
11             FileReader fr = new FileReader("./test.txt");
12             char buf[] = new char[1024];
13             while(fr.read(buf) >= 0){
14                 System.out.println(buf);
15             }
16         } catch (FileNotFoundException e) {
17             // TODO Auto-generated catch block
18             e.printStackTrace();
19         } catch (IOException e) {
20             // TODO Auto-generated catch block
21             e.printStackTrace();
22         }
23     }
24 }

Scala try catch:

 1 import java.io.FileReader
 2 import java.io.FileNotFoundException
 3 import java.io.IOException
 4 
 5 object Test {
 6    def main(args: Array[String]) {
 7       try {
 8          val f = new FileReader("input.txt")
 9       } catch {
10          case ex: FileNotFoundException =>{
11             println("Missing file exception")
12          }
13          case ex: IOException => {
14             println("IO Exception")
15          }
16       }
17    }
18 }
原文地址:https://www.cnblogs.com/shihuc/p/5081627.html