Swift语言中的错误处理

Swift语言中的错误处理,第1张

Swift语言中的错误处理 斯威夫特2&3

Swift 2中的情况有所变化,因为有了新的错误处理机制,该机制与异常有些相似,但在细节上有所不同。

1.指示错误可能性

如果函数/方法想要表明它可能抛出错误,则应包含这样的

throws
关键字

func summonDefaultDragon() throws -> Dragon

注意:函数没有实际抛出的错误类型的规范。 该声明只是声明该函数可以抛出实现ErrorType的任何类型的实例,或者根本不抛出该实例。

2.调用可能引发错误的功能

为了调用函数,您需要使用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函数:

let dragonOrNil = try? summonDefaultDragon()

这样,如果发生任何错误,您将获得返回值或nil。使用这种方式,您不会得到错误对象。

这意味着您还可以结合以下

try?
有用的语句:

if let dragon = try? summonDefaultDragon()

要么

guard let dragon = try? summonDefaultDragon() else { ... }

最后,您可以确定知道实际上不会发生错误(例如,因为您已经检查过先决条件),并使用

try!
关键字:

let dragon = try! summonDefaultDragon()

如果该函数实际引发错误,则您的应用程序中将出现运行时错误,并且该应用程序将终止。

3.引发错误

为了抛出错误,您可以使用throw这样的关键字

throw DragonError.dragonIsMissing

您可以抛出任何符合

ErrorType
协议的内容。对于初学者来说,
NSError
遵循此协议,但您可能希望使用基于枚举的枚举,
ErrorType
该枚举使您可以将多个相关的错误归为一组,并可能附加其他数据,例如:

enum DragonError: ErrorType {    case dragonIsMissing    case notEnoughMana(requiredMana: Int)    ...}

新的Swift 2和3错误机制与Java / C#/ C ++样式异常之间的主要区别如下:

  • 语法是有点不同:
    do-catch
    +
    try
    +
    defer
    VS传统的
    try-catch-finally
    语法。
  • 异常处理通常会导致异常路径中的执行时间比成功路径中的执行时间长得多。Swift 2.0错误并非如此,成功路径和错误路径的成本大致相同。
  • 必须声明所有错误抛出代码,而异常可能已从任何地方抛出。所有错误都是Java术语中的“检查的异常”。但是,与Java相比,您没有指定可能引发的错误。
  • Swift异常与ObjC异常不兼容。您的
    do-catch
    块将不会捕获任何NSException,反之亦然,因为您必须使用ObjC。
  • Swift异常与
    NSError
    返回
    false
    (对于
    Bool
    返回函数)或
    nil
    (对于
    AnyObject
    返回函数)并传递
    NSErrorPointer
    错误详细信息的Cocoa 方法约定兼容。

作为减轻错误处理的额外语法糖,还有两个概念

  • 延迟 *** 作(使用
    defer
    关键字),使您可以实现与Java / C#/ etc中的finally块相同的效果
  • 保护语句(使用
    guard
    关键字),使您编写的if / else代码比普通的错误检查/信号代码少。

斯威夫特1

运行时错误:

正如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

NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()

尽管您可能选择在ObjC代码中捕获异常,但是您无法在纯Swift中捕获它们。

问题是您是否应该为程序员错误抛出异常,还是应该像苹果在语言指南中建议的那样使用断言。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5126497.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存