为什么Scala中的模式匹配不适用于变量?

为什么Scala中的模式匹配不适用于变量?,scala,pattern-matching,match,Scala,Pattern Matching,Match,执行以下功能: 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 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")
fMatch:(s:String)单位
:12:错误:无法访问的代码
案例=>println(“它是另一回事”)
我猜这是因为它认为target实际上是一个名称,您希望分配给任何输入。两个问题:

  • 为什么会有这种行为?不能在范围中查找具有适当类型的现有变量,并首先使用这些变量,如果没有找到,则将目标视为要进行模式匹配的名称吗

  • 有解决办法吗?有没有办法让模式匹配变量?最终可以使用一个大的if语句,但match case更优雅


  • 您需要的是一个稳定的标识符。在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")
        }
    }
    
    
    

    我打赌这来自Erlang,其中变量以大写字母开头,符号以小写字母开头。请注意,
    target
    是一个值(
    val
    ),而不是一个变量(
    var
    )。它不适用于变量。大写?FORTRAN语言的阴影。弱,Martin,弱。@Emil实际上,Scala中大写的标识符表示常量。因此,大写标识符上的模式匹配意味着与常量进行比较。它对像
    Nil
    这样的东西很有帮助,我敢打赌这是真正的原因。似乎不能使用
    this
    作为一个稳定的标识符来匹配它,唯一的方法似乎是使用一个等式保护,如
    case x if x==this=>
    。可能是语法上的限制,否则它在语义上至少应该在
    object
    s中起作用。相关:我认为这个问题、代码和答案在Scala 2.12.x中已经过时了。如果作为问题的一部分提到is所适用的版本,那就太好了。