模式匹配算是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()
}