swift - 我可以从自定义init方法调用struct default memberwise init吗?

时间:2016-01-11 18:29:59

标签: swift swift-structs

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

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

我想要做的是创建一个方便的init方法来从字典中反序列化,然后字典链接到默认的成员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)在调用中给出了错误“额外参数'qty',好像它没有看到默认的成员并试图递归调用{{1} }

我可以编写自己的成员init,或者我可以直接从我的init(dictionary)分配属性,但如果我可以链接调用,那就太好了。有没有办法在swift中做到这一点?

2 个答案:

答案 0 :(得分:78)

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

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)

答案 1 :(得分:9)

来自the apple docs about Initialization

  

如果结构类型没有定义任何自己的自定义初始值设定项

,它们会自动接收成员初始值设定项

  

请注意,如果为值类型定义自定义初始值设定项,则您将无法再访问该类型的默认初始值设定项(或成员初始值设定项,如果它是结构)。这种约束可以防止有人在意外使用其中一个自动初始化程序时绕过更复杂的初始化程序中提供的其他基本设置。

因此答案是。您无法同时提供自定义初始值设定项使用成员初始值设定项。

听起来像this swift evolution proposal谈论扩展当前成员初始化程序的功能。但当然还没有结束,你仍然可以看看当前情况的局限性。