Programs written in Swift 5.8 will often have errors—a file may not exist, a division may not be possible. With try and catch, we can handle these problems.
In a do
-block, we call methods that may crash with the "try" keyword. An optional catch block is reached when an error does occur. Nothing happens if no error is raised.
This program introduces many concepts and syntax forms. It first specifies an ErrorSpecial
enum
, which is an Error. All exceptions must derive from Error.
AppendSpecial
is a worthless method, but it throws some example exceptions. Please note its use of the "throws" keyword.if
-statement that must exit the current block (as with throw) if the specified condition is not true.func
call that may throw an exception (one decorated with "throws").AppendSpecial()
is called but it throws a PartTooShort
error. We catch this and display a special message.// Some special error types. enum ErrorSpecial: Error { case PartTooShort case PartTooLong } func appendSpecial(value: String, part: String) throws -> String { // Throw an exception unless "part" is an appropriate length. guard part.count > 0 else { throw ErrorSpecial.PartTooShort } guard part.count < 10 else { throw ErrorSpecial.PartTooLong } // Append. return value + part } do { // Try to call our method. try appendSpecial(value: "cat", part: "") } catch ErrorSpecial.PartTooShort { // The method had a disaster. print("Part was too short!") }Part was too short!
An error can be converted to an optional. We use the "try?" or "try!" keywords when calling the exception-throwing method.
divideBy
method throws errors when its argument is 0. We call divideBy
twice.divideBy
func
. We evaluate the optional as part of the "if let."enum DivErrors : Error { case Invalid } func divideBy(value: Int) throws -> Int { // Throw an error if argument is equal to 0. guard value != 0 else { throw DivErrors.Invalid } return 20 / value } // Convert error to optional. // ... Then get value from optional. let result = try! divideBy(value: 10) print(result) // Prints 2. // Convert error to optional. if let result2 = try? divideBy(value: 0) { print(result2) // Not reached. }2
Another common cause of exceptions (or the need to use them) is file handling. For example, the NSString
contentsOfFile
call may throw exceptions.
In exception handling, we use an alternative control flow. This is powerful. But it introduces complexity and keywords. It is an established way to improve program quality.