Swift动态类型初始化与动态协议类型

问题描述:

我有一些实现Resource协议的结构。这定义它们必须具有符合ExtendedInfo协议的变量extendedInfo,以便通过init(json: [String: AnyObject]提供使用json初始化它们的方式。我试图提供一种方法来动态实例化这些,使用JSON,提供正确类型的ExtendedInfo并将其分配给结构的extendedInfo变量。然而,试图通过他们的dynamicTypeSwift动态类型初始化与动态协议类型

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 

任何想法家伙来实例化他们时,我得到一个Argument labels '(json:)' do not match any available overloads错误?由于

首先,你不需要明确定义的ExtendedInfoTypeAlias类型在你的结构实现中 - 你可以通过你为提供的类型来推断它。

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的事实 - 这是阻止您调用它的初始化器。


我确实发现了以下工作,即使extendedInfonil。 (This is a bug)。

user.extendedInfo = user.extendedInfo!.dynamicType.init(json: sampleJSON)

+0

太棒了。谢啦! – trundrumbalind

+0

@trundrumbalind高兴地帮助:) – Hamish

变化:

let user = User() 

要:

var user = User() 

,并尝试这个办法:

user.extendedInfo = UserExtendedInfo(json: sampleJSON) 
+0

的想法是,我没有明确说哪个'... ExtendedInfo'对象我想初始化。我希望能够从“extendedInfo”变量的类型中推断出哪一个类型,以便它可以与遵守“Resource”协议的任何对象一起工作。 – trundrumbalind