ChatGPT解决这个技术问题 Extra ChatGPT

为什么 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")

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

为什么会有这种行为?不能仅在范围内查找具有适当类型的现有变量并首先使用这些变量,如果没有找到,则将目标视为要进行模式匹配的名称?有解决方法吗?有什么方法可以对变量进行模式匹配?最终可以使用一个大的 if 语句,但 match case 更优雅。

我相信这个问题、代码和答案在 Scala 2.12.x 中已经过时了。如果在问题中提到了适用的版本,那就太好了。

B
Ben James

您正在寻找的是一个稳定的标识符。在 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")
    }
}

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


我敢打赌这来自 Erlang,其中变量以大写字母开头,符号以小写字母开头。
请注意,target 是一个值 (val),而不是一个变量 (var)。它不适用于变量。
大写? FORTRAN 的色调。弱,马丁,弱。
@Emil 实际上,Scala 中的大写标识符表示常量。因此,大写标识符上的模式匹配意味着与常量进行比较。它对 Nil 之类的东西有很大帮助, 打赌这才是真正的原因。
似乎不能使用 this 作为稳定标识符来对其进行模式匹配,唯一的方法似乎是使用像 case x if x == this => 这样的相等保护。可能是一个语法限制,否则它应该至少在 object s 内在语义上起作用。
R
Raptor0009

您也可以将其分配给案例内的临时变量,然后进行比较,这也可以

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")
    }
}



关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅