【问题标题】:Errors in Swift initialisersSwift 初始化程序中的错误
【发布时间】:2015-11-18 00:38:59
【问题描述】:

处理可能在Swift 中失败的init 的最佳方法是什么?例如,您创建了一个依赖于某个可能不可用的资源的类的实例。

显然我们有两个选择:

  • 一个可保释的 init 返回 nil(Cocoa 方式)
  • 引发错误的 init

见下文

enum ThingError: ErrorType{
    case crap
}
class Thing {
    init(c: Int) throws{
        if c < 0 {
            throw ThingError.crap
        }
    }
}



var c = try Thing(c: 3)

do{
    var d = try Thing(c: -4)
}catch{
    print("oh vey!")
}

有推荐的方法吗?第二个选项似乎更“Swifty”......

【问题讨论】:

    标签: swift cocoa swift2


    【解决方案1】:

    两者都不是天生更好或更快捷。

    我个人觉得throws 初始化器非常痛苦。我宁愿让一个失败的初始化程序返回nil,因为这样我就可以用guard let 进行初始化,而不必将东西包装在do/catch 中并处理由此产生的范围问题。您的代码说明了问题;您的 var d 被“卡在”do 范围内。我宁愿这样说:

    guard let d = Thing(c:-4) else {return}
    // now d is unwrapped and in scope!
    

    ...比这个(你要说的):

    do {
        var d = try Thing(c: -4)
    } catch {
        print("oh vey!")
    }
    // and here there is no `d`, so _now_ what?
    

    另一方面,抛出错误提供了发送消息的机会,即交流确切的问题所在。您不能仅使用 init? 初始化程序来做到这一点;它工作或失败,这就是调用者所知道的。

    【讨论】:

    • “有多少次遇到可能以多种方式失败的 init” 一直以来,@Grimxn。我立刻想到了initWithContentsOfURL:encoding:error:,还有很多很多其他的。这正是为什么在 Objective-C 中,此类方法具有 error: 指针参数的原因。该参数告诉您如何我们失败了。
    • “大多数初始化以零或一种方式失败,单个失败应该使用可失败...”我相信,@Grimxn 这就是我的回答所说 ,不是吗?
    • 你说得对 - 除了记录我自己的缓慢理解之外,我没有在这里添加任何内容。将您的评论示例添加到答案中,我将删除我的 cmets。
    猜你喜欢
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    相关资源
    最近更新 更多