9.5 case表达式里的模式变量和常量

我们已经见识了如何为要匹配的val定义占位符(比如匹配元组的ab),这些就是模式变量。不过,定义的时候需要小心。按照约定,Scala中模式变量要以小写字母开头,常量要以大写字母开头。所以,下面的代码无法通过编译。Scala会假设max是一个模式变量,即使在当前作用域内有一个有着同样名字的字段。但是匹配min的时候就不会有困难,因为它是以大写字母开头。

PatternMatching/MatchWithValsError.scala

  1. class Sample {
  2. val max = 100
  3. val MIN = 0
  4. def process(input: Int) {
  5. input match {
  6. case max => println("Don't try this at home") // Compiler error
  7. case MIN => println("You matched min")
  8. case _ => println("Unreachable!!")
  9. }
  10. }
  11. }

case表达式里,引用这种讨厌的字段时可以显式的指定作用域。(如果ObjectName是个单例或是伴生对象,可以用ObjectName.fieldName,如果obj是个引用,可以用obj.fieldName。)

上面代码修正如下:

PatternMatching/MatchWithValsOK.scala

  1. class Sample {
  2. val max = 100
  3. val MIN = 0
  4. def process(input: Int) {
  5. input match {
  6. case this.max => println("You matched max")
  7. case MIN => println("You matched min")
  8. case _ => println("Unmatched")
  9. }
  10. }
  11. }
  12. new Sample().process(100)
  13. new Sample().process(0)
  14. new Sample().process(10)

现在,输出如下:

  1. You matched max
  2. You matched min
  3. Unmatched

在真实的应用里,很快我们就会发现仅仅匹配简单的字面量、元组和对象是远远不够的。我们需要匹配更复杂的模式。Scala给了我们两个选择:case类和提取器,依次来看一下。