39

如果我创建一个没有 no 的 swift 结构init,那么我可以调用编译器生成的默认成员初始化器,如下所示:

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate
}
let o = OrderFill(price: 2, qty: 1, timeStamp: someDate)

我想做的是创建一个方便的init方法来从字典中反序列化,然后链接到默认的memberwise init。就像是

struct OrderFill {
    let price:Int
    let qty: Int
    let timeStamp: NSDate

    init(dict:[String:AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int
            qty: dict["qty"] as! Int
            timeStamp: try parseDate(dict["ts"] as! String)
    }
}
let o = OrderFill(someDict)

但是,当我尝试编写此代码时,编译器(Xcode 7.2)给了我错误“Extra argument 'qty' in call”,就好像它看不到默认成员并试图递归调用init(dictionary)

我可以编写自己的成员初始化,或者我可以直接从 my 分配属性init(dictionary),但如果我可以链接调用会很好。有没有办法快速做到这一点?

4

2 回答 2

92

添加您自己的初始化程序作为结构的扩展。扩展不能删除现有的功能,因此它将保留结构的默认初始化程序。

struct OrderFill {
    let price: Int
    let qty: Int
    let timeStamp: NSDate
}

extension OrderFill {

    init(dict: [String: AnyObject]) throws {
        self.init(
            price: dict["price"] as! Int,
            qty: dict["qty"] as! Int,
            timeStamp: try parseDate(dict["ts"] as! String)
        )
    }
}

let o = OrderFill(someDict)
于 2016-01-11T19:05:22.167 回答
9

来自关于 Initialization 的苹果文档

如果结构类型没有定义任何自己的自定义初始值设定项,则结构类型会自动接收成员初始值设定项

请注意,如果您为值类型定义自定义初始化程序,您将无法再访问该类型的默认初始化程序(或成员初始化程序,如果它是结构)。此约束可防止在更复杂的初始化程序中提供的附加基本设置被某人意外使用自动初始化程序之一规避的情况。

因此答案是否定的。您不能同时提供自定义初始化程序使用成员初始化程序。

听起来这个快速进化提案 谈论的是扩展当前成员初始化器的功能。但是,当然这还没有结束,但是您仍然可以看一下以了解当前情况的局限性。

于 2016-01-11T18:42:32.353 回答