模式匹配时可以使用类实例的字段(val
):
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
大多可以互换。
答案 0 :(得分:2)
根据reference,您的第二种情况不是有效模式。 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")
}
}
答案 1 :(得分: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")
}
但是如果要与计算值进行比较,则需要将其包含在案例陈述的if
部分中:
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")
}