Быстрая инициализация динамического типа с динамическим типом протокола

У меня есть несколько структур, которые реализуют протокол Resource. Это определяет, что они должны иметь переменную extendedInfo, которая соответствует протоколу ExtendedInfo, чтобы предоставить возможность инициализировать их с помощью json через init(json: [String: AnyObject]. Я пытаюсь предоставить способ динамического создания их экземпляров с помощью JSON, предоставляя правильный тип ExtendedInfo и назначая его переменной extendedInfo структуры. Однако я получаю сообщение об ошибке Argument labels '(json:)' do not match any available overloads при попытке создать их экземпляры через их dynamicType

protocol Resource {

    associatedtype ExtendedInfoTypeAlias: ExtendedInfo

    var extendedInfo: ExtendedInfoTypeAlias? { get set }
}

protocol ExtendedInfo {
    init(json: [String: AnyObject])
}

struct User: Resource {

    typealias ExtendedInfoTypeAlias = UserExtendedInfo

    let name: String = "Name"
    var extendedInfo: UserExtendedInfo?
}

struct UserExtendedInfo: ExtendedInfo {

    let age: Int?

    init(json: [String: AnyObject]) {
        age = json["age"] as? Int
    }
}


let user = User()
let sampleJSON = ["age": 50]

let userExtendedInfo = user.extendedInfo.dynamicType.init(json: sampleJSON) // Argument labels '(json:)' do not match any available overloads
user.extendedInfo = userExtendedInfo

Есть идеи, ребята? Спасибо


person trundrumbalind    schedule 23.04.2016    source источник


Ответы (2)


Во-первых, вам не нужно явно определять тип ExtendedInfoTypeAlias в реализации вашей структуры — вы можете просто позволить ему быть выведенным типом, который вы предоставляете для extendedInfo.

struct User: Resource {
    let name: String = "Name"
    var extendedInfo: UserExtendedInfo?
}

Во-вторых, вы можете просто использовать связанный с протоколом тип вашей данной структуры dynamicType, чтобы использовать ваш данный инициализатор. Например:

user.extendedInfo = user.dynamicType.ExtendedInfoTypeAlias.init(json: sampleJSON)
print(user.extendedInfo) // Optional(Dynamic_Protocols.UserExtendedInfo(age: Optional(50)))

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


Я обнаружил, что следующее работает, даже если extendedInfo равно nil. (Это ошибка).

<дел>user.extendedInfo = user.extendedInfo!.dynamicType.init(json: sampleJSON)

person Hamish    schedule 24.04.2016
comment
@trundrumbalind Рад помочь :) - person Hamish; 24.04.2016

Изменять:

let user = User()

To:

var user = User()

и попробуйте это:

user.extendedInfo = UserExtendedInfo(json: sampleJSON)
person Filipe Dias    schedule 23.04.2016
comment
Идея состоит в том, что я не указываю явно, какой ...ExtendedInfo объект я хочу инициализировать. Я хочу иметь возможность сделать вывод о том, какой из них относится к типу типа переменной extendedInfo, чтобы он мог работать с любым объектом, который придерживается протокола Resource. - person trundrumbalind; 24.04.2016