Swift语言中的错误处理

前端之家收集整理的这篇文章主要介绍了Swift语言中的错误处理前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我没有读过太多的Swift,但我注意到的一个事情是,没有例外。
那么他们如何在Swift中进行错误处理呢?有没有人发现任何相关的错误处理?
Swift 2& 3

事情在Swift 2中有所改变,因为有一个新的错误处理机制,它在某种程度上更类似于异常但细节不同。

1.指示错误的可能性

如果函数/方法想要表明它可能会引发错误,它应该包含这样的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)
}

或者,你可以调用throwing函数使用try?:

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 traditional try-catch-finally语法。
>异常处理通常在异常路径中比在成功路径中产生更高的执行时间。这不是Swift 2.0错误的情况,其中成功路径和错误路径成本大致相同。
>所有错误抛出代码必须声明,而异常可能已从任何地方抛出。所有错误在Java命名法中都是“checked exceptions”。但是,与Java相反,您不指定可能抛出的错误
> Swift异常与ObjC异常不兼容。你的do-catch块不会捕获任何NSException,反之亦然,因为你必须使用ObjC。
> Swift异常与返回false(用于Bool返回函数)或nil(用于AnyObject返回函数)和传递带有错误详细信息的NSErrorPointer的Cocoa NSError方法约定兼容。

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

> deferred actions(使用defer关键字),它让你实现与Java / C#/ etc中finally块相同的效果
>保护语句(使用保护关键字),如果/ else代码比正常的错误检查/信令代码更少。

Swift 1

运行时错误

由于Leandros建议处理运行时错误(如网络连接问题,解析数据,打开文件等),你应该使用像你在ObjC中的NSError,因为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中使用了异常。 Swift语言似乎没有任何语言支持异常(如throw,catch,etc关键字)。但是,由于文档建议它运行在与ObjC相同的运行时,因此你仍然能够抛出像这样的NSExceptions:

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

你只能在纯Swift中捕获它们,尽管你可以选择在ObjC代码中捕获异常。

问题是你是否应该抛出程序员错误的异常,或者使用苹果在语言指南中建议的断言。

猜你在找的Swift相关文章