我对Swift的了解还不够多,但是我注意到的一件事是没有例外。那么如何在Swift中进行错误处理呢?有没有人发现任何与错误处理相关的信息?
Swift 2中的情况有所变化,因为有了新的错误处理机制,该机制与异常有些相似,但在细节上有所不同。
如果函数/方法想要表明它可能抛出错误,则应包含这样的throws关键字
throws
func summonDefaultDragon() throws -> Dragon
注意:函数没有实际抛出的错误类型的规范。 该声明只是声明该函数可以抛出实现ErrorType的任何类型的实例,或者根本不抛出该实例。
为了调用函数,您需要使用try关键字,像这样
try summonDefaultDragon()
该行通常应该像这样出现在do-catch块中
do { let dragon = try summonDefaultDragon() } catch DragonError.dragonIsMissing { // Some specific-case error-handling } catch DragonError.notEnoughMana(let manaRequired) { // Other specific-case error-handlng } catch { // Catch all error-handling }
注意:catch子句使用Swift模式匹配的所有强大功能,因此您在这里非常灵活。
如果您正在从本身用throws关键字标记的函数中调用throwing函数,则可以决定传播错误:
func fulfill(quest: Quest) throws { let dragon = try summonDefaultDragon() quest.ride(dragon) }
另外,您可以使用try?以下命令调用throwing函数:
try?
let dragonOrNil = try? summonDefaultDragon()
这样,如果发生任何错误,您将获得返回值或nil。使用这种方式,您不会得到错误对象。
这意味着您还可以结合以下try?有用的语句:
if let dragon = try? summonDefaultDragon()
要么
guard let dragon = try? summonDefaultDragon() else { ... }
最后,您可以确定知道实际上不会发生错误(例如,因为您已经检查过先决条件),并使用try!关键字:
try!
let dragon = try! summonDefaultDragon()
如果该函数实际引发错误,则您的应用程序中将出现运行时错误,并且该应用程序将终止。
为了抛出错误,您可以使用throw这样的关键字
throw DragonError.dragonIsMissing
您可以抛出任何符合ErrorType协议的内容。对于初学者来说,NSError遵循此协议,但您可能希望使用基于枚举的枚举,ErrorType该枚举使您可以将多个相关的错误归为一组,并可能附加其他数据,例如:
ErrorType
NSError
enum DragonError: ErrorType { case dragonIsMissing case notEnoughMana(requiredMana: Int) ... }
新的Swift 2和3错误机制与Java / C#/ C ++样式异常之间的主要区别如下:
do-catch
try
defer
try-catch-finally
false
Bool
nil
AnyObject
NSErrorPointer
作为减轻错误处理的额外语法糖,还有两个概念
guard
运行时错误:
正如Leandros建议处理运行时错误(如网络连接问题,解析数据,打开文件等)一样,您应该NSError像在ObjC中一样使用,因为Foundation,AppKit,UIKit等以这种方式报告错误。因此,与其说是语言,不如说是框架。
另一个经常使用的模式是分隔符成功/失败块,例如AFNetworking中:
var sessionManager = AFHTTPSessionManager(baseURL: NSURL(string: "yavin4.yavin.planets")) sessionManager.HEAD("/api/destoryDeathStar", parameters: xwingSquad, success: { (NSURLSessionDataTask) -> Void in println("Success") }, failure:{ (NSURLSessionDataTask, NSError) -> Void in println("Failure") })
故障块仍然是频繁接收的NSError实例,描述了错误。
程序员错误:
对于程序员错误(例如对数组元素的越界访问,传递给函数调用的无效参数等),您在ObjC中使用了异常。雨燕语言似乎并未有任何异常的语言支持(如throw,catch等关键字)。但是,正如文档所示,它与ObjC在同一运行时上运行,因此您仍然可以这样抛出NSExceptions:
throw
catch
NSExceptions
NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()
尽管您可能选择在ObjC代码中捕获异常,但是您无法在纯Swift中捕获它们。
问题是您是否应该为程序员错误抛出异常,还是应该像苹果在语言指南中建议的那样使用断言。