Swift 使用动态协议类型进行动态类型初始化
Swift dynamictype initialisation with dynamic protocol type
我有许多实现 Resource
协议的结构。这定义了它们必须有一个符合 ExtendedInfo
协议的变量 extendedInfo
,以提供一种通过 init(json: [String: AnyObject]
使用 json 初始化它们的方法。我试图提供一种动态实例化这些的方法,使用 JSON,提供正确类型的 ExtendedInfo
并将其分配给结构的 extendedInfo
变量。但是,在尝试通过 dynamicType
实例化它们时出现 Argument labels '(json:)' do not match any available overloads
错误
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
有什么想法吗?谢谢
变化:
let user = User()
收件人:
var user = User()
试试这个:
user.extendedInfo = UserExtendedInfo(json: sampleJSON)
首先,你不需要在你的结构实现中显式定义 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)
我有许多实现 Resource
协议的结构。这定义了它们必须有一个符合 ExtendedInfo
协议的变量 extendedInfo
,以提供一种通过 init(json: [String: AnyObject]
使用 json 初始化它们的方法。我试图提供一种动态实例化这些的方法,使用 JSON,提供正确类型的 ExtendedInfo
并将其分配给结构的 extendedInfo
变量。但是,在尝试通过 dynamicType
Argument labels '(json:)' do not match any available overloads
错误
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
有什么想法吗?谢谢
变化:
let user = User()
收件人:
var user = User()
试试这个:
user.extendedInfo = UserExtendedInfo(json: sampleJSON)
首先,你不需要在你的结构实现中显式定义 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)