2

我是 Scala 的新手,并试图理解匹配。

当我尝试运行以下代码时,javaw VM 没有响应(一直在等待 - 从 eclipse 中尝试)

case GenericProfile(user) => processGenericProfile(_)
case _ => println("Invalid data found")

但是,以下部分可以正常工作:

case GenericProfile(user) => processGenericProfile(GenericProfile(user))
case _ => println("Invalid data found")

我试图理解为什么第一种情况无法响应。我不想通过 GenericProfile(user) - 我想知道如何简化它。谢谢!!

4

1 回答 1

8

在没有看到如何定义processGenericProfileGenericProfile定义的情况下很难确定,但我认为您的第一个案例 ( case GenericProfile(user) => processGenericProfile(_)) 只是返回一个部分应用的函数processGenericProfile,而不是将其应用于案例左侧的结果,正如我理解您想要做的那样。 ..

考虑一下这个 REPL 会话,我在其中给出了“假”定义processGenericProfileGenericProfile

scala> case class GenericProfile(user: String)
defined class GenericProfile

scala> def processGenericProfile(u: GenericProfile) = "processed"
processGenericProfile: (u: GenericProfile)java.lang.String

scala> GenericProfile("Paolo") match {
     | case GenericProfile(user) => processGenericProfile(_)
     | case _ => "wrong"
     | }
res0: java.lang.Object = <function1>

查看match?的返回类型 很可能你没有被卡住,匹配返回一个函数并且没有应用它,所以你在等待某事发生,但 scala 认为它已经完成了你想做的事情(返回一个函数)。

如果您需要捕获整个GenericProfile,而不仅仅是它包含的用户,您可以使用带有符号的别名,如下所示:@

    scala> GenericProfile("Paolo") match {
         | case u @ GenericProfile(user) => processGenericProfile(u)
         | case _ => "wrong"
         | }
    res2: java.lang.String = processed

最后一件事。我不确定“用户”case GenericProfile(user)代表什么。我写它的方式,它是一个绑定到包含在GenericProfile. 即在第一种情况下,我们说“如果我们正在检查的项目是 a GenericProfile,则获取它包含的字符串(在这种情况下为“Paolo”)并将其绑定到 name user

由于您没有在右侧使用该值,因此您还可以执行以下操作:

case u @ GenericProfile(_) => processGenericProfile(u)

其中_左侧的 明确表明您正在丢弃匹配的用户,并且您只是对检查类型是否为 a 感兴趣GenericProfile

相反,如果“用户”是您之前定义的变量(即您希望您的 case 语句检查您是否有GenericProfile特定用户的变量),那么您需要告诉 scala 这user是您定义的内容,而不是您要绑定的名称无论在GenericProfile. 这可以通过用反引号包围您的标识符(用户)来完成,如下所示:

val user="Paolo"

GenericProfile("Paolo") match {
    case u @ GenericProfile(`user`) => processGenericProfile(u) 
                                               //now this only matches                      
                                               //GenericProfile("Paolo")
    case GenericProfile(_) => "not Paolo"    
    case _ => "wrong"
}
于 2012-11-18T11:27:08.483 回答