为什么 Scala 中的模式匹配不能与变量一起工作?

履行以下职能:

def fMatch(s: String) = {
s match {
case "a" => println("It was a")
case _ => println("It was something else")
}
}

这种模式非常匹配:

scala> fMatch("a")
It was a


scala> fMatch("b")
It was something else

我希望能够做到以下几点:

def mMatch(s: String) = {
val target: String = "a"
s match {
case target => println("It was" + target)
case _ => println("It was something else")
}
}

这会产生以下错误:

fMatch: (s: String)Unit
<console>:12: error: unreachable code
case _ => println("It was something else")

我猜这是因为它认为 target 实际上是您希望分配给任何输入的名称。两个问题:

  1. Why this behaviour? Can't case just look for existing variables in scope that have appropriate type and use those first and, if none are found, then treat target as a name to patternmatch over?

  2. 有解决办法吗?有没有什么方法可以对变量进行模式匹配?最终,我们可以使用一个大的 if 语句,但匹配用例更优雅。

37358 次浏览

你要找的是 稳定标识符。在 Scala 中,它们必须以大写字母开头,或者被反勾环绕。

这两种方法都可以解决你的问题:

def mMatch(s: String) = {
val target: String = "a"
s match {
case `target` => println("It was" + target)
case _ => println("It was something else")
}
}


def mMatch2(s: String) = {
val Target: String = "a"
s match {
case Target => println("It was" + Target)
case _ => println("It was something else")
}
}

为了避免意外地引用已经存在于封闭范围中的变量,我认为默认行为是小写模式为变量而不是稳定标识符是有意义的。只有当您看到以大写字母开头的内容或以反勾号开头的内容时,才需要注意它来自周围的范围。

您还可以将它分配给案例中的一个临时变量,然后对它进行比较,这也是可行的

def mMatch(s: String) = {
val target: String = "a"
s match {
case value if (value ==target) => println("It was" + target) //else {} optional
case _ => println("It was something else")
}
}