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类添加了例如equals,hashCode,以及toString等class方法,我们不需要自己再写相关的方法了。