为了账号安全,请及时绑定邮箱和手机立即绑定

Swift语言中的错误处理

Swift语言中的错误处理

眼眸繁星 2019-08-12 09:51:26
Swift语言中的错误处理我没有读过太多关于Swift的信息,但我注意到的一件事是没有例外。那么他们如何在Swift中进行错误处理呢?有没有人发现任何与错误处理相关的内容?
查看完整描述

3 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

斯威夫特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关键字的函数调用throw函数,则可能决定传播错误:

func fulfill(quest: Quest) throws {
    let dragon = try summonDefaultDragon()
    quest.ride(dragon)}

或者,您可以使用try?以下方法调用throw函数:

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,这符合这个协议,但你可能希望使用基于enum的方法ErrorType,这样你就可以将多个相关的错误分组,可能还有额外的数据,比如这个

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

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

  • 语法有点不同:do-catchtrydefervs传统try-catch-finally语法。

  • 异常处理通常会在异常路径中产生比在成功路径中高得多的执行时间。Swift 2.0错误的情况并非如此,其中成功路径和错误路径的成本大致相同。

  • 必须声明所有错误抛出代码,而异常可能从任何地方抛出。所有错误都是Java命名法中的“已检查异常”。但是,与Java相比,您不指定可能抛出的错误。

  • Swift异常与ObjC异常不兼容。您的do-catch块不会捕获任何NSException,反之亦然,因为您必须使用ObjC。

  • Swift异常与NSError返回falseBool返回函数)或nilAnyObject返回函数)和传递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中使用了异常。雨燕语言似乎并未有任何异常的语言支持(如throwcatch等关键字)。但是,正如文档所示,它与ObjC在同一运行时运行,因此您仍然可以NSExceptions像这样抛出:

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

虽然您可以选择在ObjC代码中捕获异常,但您无法在纯Swift中捕获它们。

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


查看完整回答
反对 回复 2019-08-12
?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

Swift中没有Exceptions,类似于Objective-C的方法。

在开发过程中,您可以assert用来捕获可能出现的任何错误,并且需要在投入生产之前进行修复。

经典的NSError方法没有改变,你发送一个NSErrorPointer,填充。

简要示例:

var error: NSError?var contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/Users/leandros", error: &error)if let error = error {
    println("An error occurred \(error)")} else {
    println("Contents: \(contents)")}


查看完整回答
反对 回复 2019-08-12
  • 3 回答
  • 0 关注
  • 635 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信