Swift's explanation of Error handling
Official Apple Document explanation
Like other languages, Swift's exception handling is the processing logic after the program throws an exception. Swift provides best-in-class exception-throwing, capturing, and processing capabilities. Similar to the Java language, Swift's exception is not a real program crash, but rather a logical branch of the program's operation, and the timing of catching exceptions from Swift and Java is the same. When the SWIFT runtime throws an exception and is not processed, the program crashes.
Use error in the swift language to represent an exception that works with the exception class of Java or the Nserror class of Object-c. Apple recommends using enumerations as exception types (why not use classes or structs?). The answer is that the enumeration data type itself is divided into several cases, which is well suited to the logical branching criterion.
enum Vendingmathineerror:error { case invalidselection case Insufficientfunds (coinsneed:int) case Outofstack}
The enumeration type Vendingmathineerror is declared above, which inherits from error. Note that all exception types for Swift are inherited from error, just as Java all exception classes inherit from exception.
Similar to Java's try/catch/finally for handling exceptions, Swift provides a try, try, try!, catch, throw, throws keyword handling exception logic, which is much like Java.
How do I declare a function that might throw an exception? Add the throws keyword after the function parameter parentheses, a bit like the Java syntax; the difference is that Swift's throws is not followed by the exception class, and Java's throws is followed by an exception class name. All you have to do is tell Swift that the function might throw an exception, and that there is no need to explain exactly what kind of exception the body can throw any type of exception (which is definitely inherited from error).
Func canthrowerrors () throws-String
Func canthrowerrors (type:int) throws-String? { //function Body written switch/case better ifType = =1 { ThrowVendingmathineerror.invalidselection}ifType = =2 { ThrowVendingmathineerror.outofstack}ifType = =3 { ThrowVendingmathineerror.insufficientfunds (coinsneed: -) } return "Success"}
The above test code is to test throw the exception logic, function body written switch/case better. As seen from the Canthrowerrors function, when the argument is 1, 2, or 3 throws an exception, the syntax is throw ... And the program will jump out of the function body, syntax and Java.
Swift provides a syntax similar to Java Try/catch, which is do (the function body must have a try and the statement may throw an exception ), catch.
Do {try expression catch1 { catch2 where condition { statements}
Note: If the try statement throws an exception, it jumps out of the do block and catches sequentially by catch, and after a catch capture succeeds, subsequent catch is no longer executed.
Do{var data=TryCanthrowerrors (Type:3)//execute this function may throw an exception print ("After execute canthrowerrors") ifData! =Nil {print ("Error Test data:\ (data)") }} Catchvendingmathineerror.outofstack {print ("Outofstack")} Catchvendingmathineerror.invalidselection {print ("invalidselection")} Catch{//Java-like catch (Exception ex)Print"Error")}
Output: Error
Try Canthrowserrors (Type:3) throws Vendingmathineerror.issufficientfunds (coinsneed:100), which does not belong to the first 2 catch types, And the last catch is to catch all exceptions, all of which will execute its function body.
Do you feel a little bit less? Yes, we're missing a Java-like finally, which is described later.
What about try? and try! The usage.
try? somethrowingfunction () // the same as the following Do { try somethrowingfunction ()}catch { = Nil}
Try The following statement may throw an exception, and if thrown an exception is assigned nil to the left, and if no exception is thrown, the return value is assigned to the left;
try! Remove the exception capture logic, the syntax is a little wayward, the equivalent of a bare-Ben , knowingly may throw an exception, but confident that the code will not throw an exception. try! A try? The supplement. You are sure that the subsequent statement will not throw an exception, but the program will crash after it throws an exception. Use of try! is not recommended , is it recommended to use try?
Try 1) // If you throw an exception program to run normally and assign nil to the left, assign the return value to the left if no exception is thrown // Let tmpy = try! canthrowerrors (type:2) // you're pretty sure you won't throw an exception, but if the runtime throws an exception, the program crashes.
Swift uses the defer keyword to work with the finally of Java, even if there is a break, continue, return, or throw exception within the code block, the defer code block will still execute after exiting the code block
The following code is just for testing, verifying that the execution timing of an exception is thrown in the function body, the syntax logic is exactly the same as finally.
Func Testdefer (_ Param:int) throws, String { print ("testdefer begin" /c14>)
Defer {//throws an exception to execute defer to throw an exception and then executes defer print ("Testdefer exit" )}
// do something ...
if 1 { throw vendingmathineerror.invalidselection } print (" Testdefer End")return"testdefer return " }// Call function This function throws an exception Tmpz = niltry? Testdefer (1)
Output: Testdefer Begintestdefer exit
No defer throw exception execution logic
func testdefernormal () { print ("testdefer begin") defer { Print ("testdefer exit") } print (" Testdefer End")}testdefernormal ()
Swift-Exception handling