Подтвердить что ты не робот

Swift - могу ли я вызвать init по умолчанию элемента по умолчанию из моего пользовательского метода init?

Если я создаю быструю структуру без init, тогда я могу вызвать созданный компилятором инициализатор по умолчанию по умолчанию, например:

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

То, что я хотел бы сделать, это создать метод инициализации удобства для десериализации из словаря, который затем соединяется с 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 "в вызове", как будто он не видит по умолчанию по умолчанию и пытается рекурсивно вызвать init(dictionary)

Я могу написать собственный собственный init init или просто назначить свойства непосредственно из моего init(dictionary), но было бы неплохо, если бы я мог связать вызов. Есть ли способ сделать это быстрым?

4b9b3361

Ответ 1

Добавьте свой собственный инициализатор в качестве расширения вашей структуры. Расширения не могут удалить существующие функции, поэтому он сохранит инициализатор структуры по умолчанию.

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)

Ответ 2

Из яблочные документы об инициализации:

Типы структуры автоматически получают член-инициализатор, если они не определяют никаких собственных собственных инициализаторов

и

Обратите внимание, что если вы определяете пользовательский инициализатор для типа значения, у вас больше не будет доступа к инициализатору по умолчанию (или инициализатору по умолчанию, если это структура) для этого типа. Это ограничение предотвращает ситуацию, при которой дополнительная существенная настройка, предоставляемая в более сложном инициализаторе, обходит кем-то случайно, используя вместо этого один из автоматических инициализаторов.

Поэтому ответ NO. Вы не можете предоставить пользовательский инициализатор и использовать инициализатор по порядку в одно и то же время.

Похоже, что это быстрое предложение эволюции говорит о расширении возможностей текущего инициализатора по порядку. Но, конечно, это еще не все, но вы можете все же взглянуть, чтобы немного узнать о том, каковы ограничения текущей ситуации.