Scala 为什么val是稳定标识符而def不是?

Scala 为什么val是稳定标识符而def不是?,scala,pattern-matching,Scala,Pattern Matching,模式匹配时可以使用类实例的字段(vals): 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) // =

模式匹配时可以使用类实例的字段(
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
基本上是可以互换的。

根据,您的第二个案例不是有效的模式
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")
  }
} 

我相信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")
}
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")
}
但如果要与计算值进行比较,则需要将其包含在案例陈述的
if
部分中:

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")
}
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")
}
tomsWeddingDate匹配{
案例日期:LocalDate如果dateprintln(“呸,我还有时间买礼物。”)
case=>println(“哎呀,我想我需要寄一张迟到的卡片”)
}

井的可能重复,val是常数,def是函数定义。它可以工作,但将空函数定义视为常量可能不是一个好主意。。。或者值得努力。@marius不,我认为这不是重复。@BoldizárNémeth这个问题的答案将完全相同。那么,为什么这不是重复的呢?为了进一步调查:自定义
的实现可能还取决于某些全局
var
的状态。我认为
def
并不比
unapply
差。稳定的标识符是以标识符结尾的路径。为什么
a.bar
不是一个稳定的标识符?我已经阅读了
§8.1.5
,但仍然不明白为什么禁止
a.bar
a.bar
不是一个标识符,而是一个声明