了解Scala中的catch

时间:2016-11-14 19:00:34

标签: scala exception try-catch

我写了以下简单的例子:

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出了什么问题?

1 个答案:

答案 0 :(得分:4)

提取

Read about extractors

你正在处理提取器。不只是在catch子句中,而是在处理模式匹配时。对模式匹配进行了一些复杂类型的去除。

使用对象中的unapply方法将复杂类型解压缩为简单元组。

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

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

出现编译错误。

None不是throwable,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