为什么 Scala 中的模式匹配不适用于变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7078022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does pattern matching in Scala not work with variables?
提问by Henry Henrinson
Take the following function:
取以下函数:
def fMatch(s: String) = {
s match {
case "a" => println("It was a")
case _ => println("It was something else")
}
}
This pattern matches nicely:
这种模式很好地匹配:
scala> fMatch("a")
It was a
scala> fMatch("b")
It was something else
What I would like to be able to do is the following:
我希望能够做的是以下内容:
def mMatch(s: String) = {
val target: String = "a"
s match {
case target => println("It was" + target)
case _ => println("It was something else")
}
}
This gives off the following error:
这会产生以下错误:
fMatch: (s: String)Unit
<console>:12: error: unreachable code
case _ => println("It was something else")
I guess this is because it thinks that target is actually a name you'd like to assign to whatever the input is. Two questions:
我想这是因为它认为目标实际上是您想要分配给任何输入的名称。两个问题:
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?
Is there a workaround for this? Any way to pattern match against variables? Ultimately one could use a big if statement, but match case is more elegant.
为什么会有这种行为?不能只在范围内查找具有适当类型的现有变量并首先使用它们,如果没有找到,则将目标视为名称以进行模式匹配吗?
有解决方法吗?有什么方法可以对变量进行模式匹配?最终可以使用一个大的 if 语句,但 match case 更优雅。
回答by Ben James
What you're looking for is a stable identifier. In Scala, these must either start with an uppercase letter, or be surrounded by backticks.
您正在寻找的是一个稳定的标识符。在 Scala 中,它们必须以大写字母开头,或者被反引号包围。
Both of these would be solutions to your problem:
这两种方法都可以解决您的问题:
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")
}
}
To avoid accidentally referring to variables that already existed in the enclosing scope, I think it makes sense that the default behaviour is for lowercase patterns to be variables and not stable identifiers. Only when you see something beginning with upper case, or in back ticks, do you need to be aware that it comes from the surrounding scope.
为了避免意外引用封闭范围中已经存在的变量,我认为默认行为是小写模式是变量而不是稳定标识符是有道理的。只有当您看到以大写字母开头或以反引号开头的内容时,您才需要意识到它来自周围的范围。

