5

val模式匹配时可以使用类实例的字段( s):

class A {
  val foo = 37
  def bar = 42
}

def patmat1(a: A, x: Int) {
  x match {
    case a.foo => println("a.foo")
    case _     => println("not a.foo")
  }
}

patmat1(new A, 37) // => a.foo
patmat1(new A, 42) // => not a.foo

我想知道为什么def不能类比使用?

def patmat2(a: A, x: Int) {
  x match {
    case a.bar => println("a.bar")
    //     ^ error: stable identifier required, but a.bar found.
    case _     => println("not a.bar")
  }
}

我是这么想的,val而且def大部分是可以互换的。

4

2 回答 2

2

根据参考,您的第二种情况不是有效模式。val foo之所以有效,是因为它是一个稳定的标识符模式§ 8.1.5,这基本上意味着它会检查x == a.foo.

您的第二种情况根本不是任何有效的模式(因为a.bar不是标识符而是声明),因此是错误的。

一种惯用的方式是:

def patmat1(a: A, x: Int) {
  x match {
    case i if a.bar == x => println("a.foo")
    case _     => println("not a.foo")
  }
} 
于 2013-09-16T08:22:48.243 回答
0

我相信 case 语句左半部分的第一部分是解构一个对象或将其匹配到一个常量值。因此,例如:

val animal: Animal = Dog("butch",4)

animal match {
  case _: Dog => println("bow-wow")
  case _: Cat => println("meow")
}

如果要与常量进行比较,可以在 case 语句的主要部分进行:

secretConstant match {
  case Math.PI => println("I'm a PI")
  case Math.E  +> println("I'm an E")
  case _ => println("I don't know what I am")
}

但是,如果要与计算值进行比较,则需要将其包含在ifcase 语句的部分中:

tomsWeddingDate match {
  case date: LocalDate if date < LocalDate.now() => println("phew, I still have time to buy a gift.")
  case _ => println("Oops, I guess I need to send a belated card")
}
于 2013-09-16T08:41:08.193 回答