猿问

在Swift中实现失败的初始化程序的最佳实践

通过以下代码,我尝试定义一个简单的模型类,它是可失败的初始化器,该初始化器将(json-)字典作为参数。nil如果用户名未在原始json中定义,则初始化程序应返回。


1.为什么不编译代码?错误消息显示:


从初始化器返回nil之前,必须初始化类实例的所有存储属性。


那没有道理。为什么计划返回时初始化那些属性nil?


2.我的方法正确吗?或者是否有其他想法或通用模式可以实现我的目标?


class User: NSObject {


    let userName: String

    let isSuperUser: Bool = false

    let someDetails: [String]?


    init?(dictionary: NSDictionary) {

        if let value: String = dictionary["user_name"] as? String {

            userName = value

        }

        else {

           return nil

        }


        if let value: Bool = dictionary["super_user"] as? Bool {

            isSuperUser = value

        }


        someDetails = dictionary["some_details"] as? Array


        super.init()

    }

}


杨魅力
浏览 487回答 3
3回答

largeQ

那没有道理。当我计划返回nil时,为什么要初始化那些属性?根据Chris Lattner的说法,这是一个错误。他说的是:这是发行说明中记录的swift 1.1编译器中的实现限制。编译器当前无法在所有情况下销毁部分初始化的类,因此它不允许形成必须这样做的情况。我们认为此错误是在将来的版本中修复的,而不是功能。资源编辑:因此,swift现在是开源的,并且根据此变更日志,现在已在swift 2.2的快照中对其进行了修复。现在,在对象已完全初始化之前,声明为失败或抛出的指定类初始化器可能分别返回nil或抛出错误。

守候你守候我

我接受Mike S的回答是Apple的推荐,但我认为这不是最佳实践。一个强类型系统的重点是将运行时错误转移到编译时。这种“解决方案”无法达到目的。恕我直言,最好是继续将用户名初始化为"",然后在super.init()之后检查它。如果允许使用空白的用户名,则设置一个标志。class User: NSObject {    let userName: String = ""    let isSuperUser: Bool = false    let someDetails: [String]?    init?(dictionary: [String: AnyObject]) {        if let user_name = dictionary["user_name"] as? String {            userName = user_name        }        if let value: Bool = dictionary["super_user"] as? Bool {            isSuperUser = value        }        someDetails = dictionary["some_details"] as? Array        super.init()        if userName.isEmpty {            return nil        }    }}
随时随地看视频慕课网APP
我要回答