【问题标题】:Understanding catch in Scala理解 Scala 中的 catch
【发布时间】:2017-03-28 12:19:39
【问题描述】:

我写了以下简单的例子:

def main(args: Array[String]) = {
    try{
      throw new IllegalArgumentException
    } catch {
      case Ex(e) => println("IllegalArgumentException was thrown")
    }
}

object Ex{
  def unapply(arg: Throwable): Option[Throwable] = arg match {
    case arg: IllegalArgumentException => Some(arg)
    case _ => None
  }
}

并且对它的工作感到非常困惑。在 catch 子句中,我们甚至没有声明 e。另一个是在 catch 子句中我们匹配Some[Throwable],而不是Throwable 本身。因此,我尝试执行以下操作:

catch {
      case Ex(e) => println("IllegalArgumentException was thrown")
      case None => println("None")  //error, found None.type required Throwable
    }

它没有工作。为什么?我们匹配了Some[Throwable]None 怎么了?

【问题讨论】:

  • @pamu 对,你的问题是关于提取器而不是真正的例外。

标签: scala exception try-catch


【解决方案1】:

提取器

Read about extractors

您正在处理提取器。不仅在 catch 子句中,而且在您处理模式匹配时。一些复杂类型的脱糖是为了模式匹配。

使用对象中的unapply 方法将复杂类型脱糖成简单元组。

在您的情况下,当 Ex(e) 用于内部模式匹配时,会调用 unapply 方法。 unapply 方法的返回类型应该是某个元组的Option,也可以是单个值。

所以当None 返回时匹配失败。当 Some 返回时,scala 会尝试匹配元组的内部值。

来到编译错误。

None 不是可抛出的,并且 None 不是 unapply 方法返回 Option[Throwable] 的对象,因此,Scala 编译器会给出编译错误。

例如。

Scala REPL

class Foo(val a: Int)

object Foo {
  def unapply(foo: Foo): Option[Int] = Some(foo.a)
}

scala> class Foo(val a: Int)
defined class Foo

scala>

scala> object Foo {
     |   def unapply(foo: Foo): Option[Int] = Some(foo.a)
     | }
defined object Foo
warning: previously defined class Foo is not a companion to object Foo.
Companions must be defined together; you may wish to use :paste mode for this.

scala> new Foo(10) match { case Foo(value) => println("matched: " + value) }
matched: 10

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 2016-10-20
    • 2017-03-26
    • 2014-04-10
    • 2015-10-21
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多