Apple did announce Swift 2.0 at WWDC 2015 yesterday. Here are some links:
Lot of nice changes, but some of them are weird. Especially error handling.
Swift 1.2 pattern
An example of error handling pattern in Swift < 2:
Pretty straightforward and readable.
New version of Swift introduces weird error handling IMO. Here’s an example. Lets create
ATM class with
throws keyword in
withdraw function declaration. It basically
says that this function can throw an error. But you can’t specify which error it can
throw. Readability, safety, … don’t get it why. Anyway, next step is to handle these
Verbosity, verbosity, …
- Every call which can throw must be marked with
try. You are going to get Call can throw but is not marked with ‘try’ error if it is not marked properly.
- To scope your
catchyou have to use
do. Why not
trymark in calls? Who knows. Probably because of
Next new thing is
defer. This block of code is executed at the end of the scope (error thrown, return, …). You’re not forced to use it with
only. It’s a general statement which can be used in this way as well:
Put verbosity aside for now. Remove last
error and try to compile it. It succeeds. Hmmm. It shouldn’t. At least warning
that some errors are not handled would be nice. Or force me to use:
We’re humans, we make mistakes, … Do you remember how long we had to wait for
NS_ENUM in Objective-C, so, clang can provide some useful warnings?
Passing errors is pretty straightforward.
throws keyword in
doSomething() declaration and don’t forgot to
try. Things are going to be weird with
try!. What’s this? You’re saying
that you do know that error will not be thrown in this case and then you can omit error
Things are going to be more messy. I’m a good citizen and would like to handle
errors in higher level because of this
try! in my code or for whatever reason.
No way, warning: ‘catch’ block is unreachable because no errors are thrown in ‘do’
block. Hmm, should try with
No way. Same warning plus new one: No calls to throwing functions occur within ‘try’
expression. Hmm, should try with
No warnings, yes! Compile, run and
SIGABRT. What? Don’t use
try! at all.
try! whatever() call throws an error, there’s no way to handle it
and it always ends up with
Swift is fast and safe. But it looks like that safety was sacrificed for speed in this
case. We have to wait for source code of Swift compiler to get reasoning behind this
decision and to get an answer why it was done in this way.
It looks weird to me for now and I don’t like it. I don’t like exceptions at all (wonder
why they call them errors in Swift 2.0) and I hope that Apple is not going to use them heavily in upcoming frameworks.
enum Result<T, E> …