模式匹配算是scala中最有用的部分之一
匹配值:
val times = 1 times match { case 1 => "one" case 2 => "two" case _ => "some other number" }
使用守卫判断:
times match { case i if i == 1 => "one" case i if i == 2 => "two" case _ => "some other number" }
匹配类型
def bigger(o: Any): Any = { o match { case i: Int if i < 0 => i - 1 case i: Int => i + 1 case d: Double if d < 0.0 => d - 0.1 case d: Double => d + 0.1 case text: String => text + "s" } }
注意:匹配类型只能用在参数传递或者父类引用指向子类对象时,才会有效(匹配是哪种子类对象)。直接使用会出现错误:
val times = 1 times match { case i: Int if i > 0 => println("Int") case i: Int => println("Int small") case d: Double => println("Double") case t: String => println("String") case _ => println("others") }
因为times在传给i,d,t时,类型已经确定了,就是Int型的,用他去匹配Double和String肯定会有问题:
<console>:12: error: scrutinee is incompatible with pattern type; found : Double required: Int case d: Double => println("Double") ^ <console>:13: error: scrutinee is incompatible with pattern type; found : String required: Int case t: String => println("String") ^
但是以这种方式匹配类中的基本信息,就会很麻烦:
ef calcType(calc: Calculator) = calc match { case _ if calc.brand == "hp" && calc.model == "20B" => "financial" case _ if calc.brand == "hp" && calc.model == "48G" => "scientific" case _ if calc.brand == "hp" && calc.model == "30B" => "business" case _ => "unknown" }
所以scala提供了样式类,来更方便的匹配类中的信息:
scala> case class Calculator(brand: String, model: String) defined class Calculator scala> val hp20b = Calculator("hp", "20b") hp20b: Calculator = Calculator(hp,20b)
val hp20b = Calculator("hp", "20B") val hp30b = Calculator("hp", "30B") def calcType(calc: Calculator) = calc match { case Calculator("hp", "20B") => "financial" case Calculator("hp", "48G") => "scientific" case Calculator("hp", "30B") => "business" case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel) }
注意:样式类已经实现了性等性和易读的toString()方法。
scala> val hp20b = Calculator("hp", "20b") hp20b: Calculator = Calculator(hp,20b) scala> val hp20B = Calculator("hp", "20b") hp20B: Calculator = Calculator(hp,20b) scala> hp20b == hp20B res6: Boolean = true
在scala的异常处理中,也使用到了模式匹配:
try { remoteCalculatorService.add(1, 2) } catch { case e: ServerIsDownException => log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.") } finally { remoteCalculatorService.close() }
浙公网安备 33010602011771号