我写了以下简单的例子:
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
出了什么问题?
答案 0 :(得分:4)
你正在处理提取器。不只是在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