【问题标题】:Is there a full specification for pattern matching possibilities of Scala?Scala 的模式匹配可能性是否有完整的规范?
【发布时间】:2011-10-01 06:04:37
【问题描述】:

是否有关于 Scala 的模式匹配可能性的完整规范?

我无法修复以下代码:

  something match {
    case e @ (sae: ServerApiException if sae.statusCode == 401 | _: UnauthorizedException) => {
      doSomething(e)
    }
    ...
  }

(在 2.8.1 中无法编译。)

【问题讨论】:

  • 不是最具描述性或最有用的问题标题......它非常模糊,人们可能会直接滚动过去,除非他们此刻感到无聊。实际上,正文中的第一行应该是一个更好的标题(“Scala 的模式匹配可能性有完整的规范吗?”)。
  • 给我们一个关于什么不起作用的线索。编译错误?运行时结果错误?例外?

标签: scala pattern-matching


【解决方案1】:

我不确定我是否会这样编写代码;很难理解(除了不能以原始形式工作)。

我宁愿选择类似的东西

def doSomething(e: Exception) = { /* whatever */ }
something match {
  case sae: ServerApiException if (sae.statusCode == 401) => doSomething(sae)
  case ue: UnauthorizedException => doSomething(ue)
}

避免重复代码。或者你可以使用选项:

(something match {
  case sae: ServerApiException if (sae.statusCode == 401) => Some(sae)
  case ue: UnauthorizedException => Some(ue)
  case _ => None
}).foreach(e => /* do something */ )

如果您更愿意在之后编写该方法。但我认为第一种方法可能是最清楚的。

【讨论】:

  • 选项让你写(something match { /* blah */ }).foreach(e => /* whatever */),其中只有那些匹配并变成Some(x)的案例将通过并在e中传递foreach 步骤。 None 案例将无济于事。因此 option/foreach 方法与方法 def 版本完全相同,只是步骤的顺序不同,并且保证您不能将 doSomething 方法用于其他任何事情(因为它不是t 命名——它只是第二种情况下e => 之后的代码)。
  • 但是其他情况如何处理(...)?
  • 您没有具体说明您担心的其他情况。
  • 还有一些例外。
  • 把每一个你想处理的Some包装起来,让其他的都交给None
【解决方案2】:

Chapter 8 of the Scala Language Spec? (pdf).

更具体地说,this answer 可能会有所帮助,即您应该能够执行以下操作:

case e: Exception if e.isInstanceOf[UnauthorizedException] || (e.isInstanceOf[ServerApiException] && e.asInstanceOf[ServerApiException].statusCode == 401) => {
    doSomething(e)
}

【讨论】:

  • 它无法编译,因为Exception 没有statusCode 成员。
  • @TN:编辑添加显式演员表,实际上尝试编译此版本。不过,几乎不是最漂亮的代码......
【解决方案3】:

最后,我在 Scala 语言规范(Scala 语法摘要)的帮助下做到了这一点:

  something match {
    case e: Exception if (e match {
      case sae: ServerApiException if sae.statusCode == 401 => true
      case _: UnauthorizedException => true
      case _ => false
    }) => {
      doSomething(e)
    }
    ...
  }

【讨论】:

  • 我更喜欢这个,而不是我前进的方向。
  • 我想实际的上下文可能更复杂,但这个具体的例子可能更直接,如something match { case sae:ServerApiException if sae.statusCode == 401 => doSomething(sae); case ue: UnauthorizedException => doSomething(ue); }
  • 是的,实际代码doSomething 更复杂,因此我正在寻找“更好”的解决方案。
猜你喜欢
  • 2023-03-12
  • 2023-03-29
  • 1970-01-01
  • 2012-12-27
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多