Closures that Throw: Rethrows in Swift 2

Once you've mastered throwing and catching errors, there's a whole new world awaiting you: functions (or methods) that take a closure that throws, but which you don't want the function to handle. To work with this there is rethrowing and the accompanying keyword rethrows:
enum NumberError:ErrorType {
    case ExceededInt32Max
}

func functionWithCallback(callback:(Int) throws -> Int) rethrows {
    try callback(Int(Int32.max)+1)
}

do {
 try functionWithCallback({v in if v <= Int(Int32.max) { return v }; throw NumberError.ExceededInt32Max})
}
catch NumberError.ExceededInt32Max {
    "Error: exceeds Int32 maximum"
}
catch {
}
Internally the rethrowing function uses the try keyword as usual, but does not require the do and catch elements. It is only when the function is called that the do-try-catch syntax is employed.

As David Steuber points out, you can simply use throws in place of rethrows and nothing changes, all will work in the given scenario, although there are behavioural reasons, in addition to the semantics, to use rethrows:
"A throwing method can't override a rethrowing method, and a throwing method can't satisfy a protocol requirement for a rethrowing method. That said, a rethrowing method can override a throwing method, and a rethrowing method can satisfy a protocol requirement for a throwing method."
This behaviour clarifies intentions by imposing restrictions. And now we're more than ready to start throwing things.


Comments

  1. Again superlative content, format your blog so one can actually consume knowledge unarduously.

    Black and white OKAY but that line wrapping is abhorrent.

    ReplyDelete
  2. this is a terrible comment. You are being ungrateful and condescending aka an american. Are you an American ?

    ReplyDelete

Post a Comment