Reputation: 27455
I wrote the following simple example:
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
}
}
and was pretty confused by that it's working. In the catch clause we didn't even declare e
. And another was that in the catch clause we match against Some[Throwable]
, not the Throwable
itself. So, I tried to do the following:
catch {
case Ex(e) => println("IllegalArgumentException was thrown")
case None => println("None") //error, found None.type required Throwable
}
and it didn't work. Why? We matched against Some[Throwable]
. What's wrong with None
?
Upvotes: 1
Views: 123
Reputation: 14825
Your are dealing with extractor. Not just in catch clause, but when ever you are dealing with pattern matching. The desugaring of some complex type is done to pattern match.
De-sugaring the complex type into simple tuple is done using the unapply
method in the object.
In your case when Ex(e)
is used for pattern matching internally unapply
method is called. The return type of unapply method should be Option
of some tuple it could be single value as well.
So when None
is returned the match fails. When Some is returned scala tries to match the inner value of tuple.
Coming to the compilation error.
None is not throwable and None is not a object whose unapply method returns Option[Throwable] so, Scala compiler gives compilation error.
For Example.
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
Upvotes: 4