【问题标题】:Catching MatchError at val initialisation with pattern matching in Scala?在 Scala 中使用模式匹配在 val 初始化时捕获 MatchError?
【发布时间】:2012-01-18 10:40:45
【问题描述】:

在使用模式匹配分配值时,捕获MatchError 的最佳方式是什么(最简洁、最清晰、最惯用)?

例子:

val a :: b :: Nil = List(1,2,3) // throws scala.MatchError

到目前为止我发现的最好方法:

val a :: b :: Nil = try {
    val a1 :: b1 :: Nil = List(1,2,3)
    List(a1, b1)
  catch { case e:MatchError => // handle error here }

有没有一种惯用的方法来做到这一点?

【问题讨论】:

  • 你也可以使用scala.util.control.Exception
  • 预期的行为是什么?
  • 如果模式匹配分配失败,MatchError 不正是您想要抛出的东西吗?否则我会亲自使用其他控制结构以不同方式处理问题。

标签: scala


【解决方案1】:

为什么不简单

val a::b::Nil = List(1,2,3) match {
  case a1::b1::Nil => {
    a1::b1::Nil
  }
  case _ => //handle error
}

?

【讨论】:

  • 这仍然是 4 行长,而且在复杂的模式匹配中会出现荒谬的代码重复。
  • 在复杂的模式匹配中,使用带有异常的多个赋值将是一团糟。 Kim 的回答是最惯用的。
【解决方案2】:

对 Kim 的解决方案略有改进:

val a :: b :: Nil = List(1, 2, 3) match {
  case x @ _ :: _ :: Nil => x
  case _ => //handle error
}

如果您能提供有关如何处理错误的更多信息,我们可以为您提供更好的解决方案。

【讨论】:

  • 关于处理 - 可能只是抛出一个适当的异常。
【解决方案3】:

以下内容没有捕获错误,但避免了(一些;参见 Nicolas 的评论)它。我不知道提问者是否对此感兴趣。

scala> val a :: b :: _ = List(1,2,3)
a: Int = 1
b: Int = 2

【讨论】:

  • 如果你有少于 2 个元素,它不会避免任何事情。
【解决方案4】:

简单的解决办法是这样的:

List(1, 2, 3) match {
   case a :: b :: Nil => .....
   case _ => // handle error
}

我不喜欢匹配两次,因为它是多余的。 只有当您确定它匹配时,才应该使用带有模式匹配的“val”,或者添加一个 try /catch 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多