具有协议类型的Swift字典作为密钥 [英] Swift Dictionary with Protocol Type as Key
问题描述
简单的问题在这里:
我得到一个协议协议SCResourceModel {..}
和一个字典,使用此协议类型作为密钥: [SCResourceModel:String]
。
这显然不起作用,因为字典中的关键字必须符合协议 Hashable
。让我的 SCResourceModel
继承自 Hashable
或尝试这样的东西 [protocol< SCResourceModel,Hashable>因为
Hashable
或 Equable
只能是用作通用约束,而不是类型本身。
I got a protocol protocol SCResourceModel {..}
and a dictionary which shall use this protocol type as key: [SCResourceModel : String]
.
This obviously does not work, as a key in a dictionary has to conform to the protocol Hashable
. Making my SCResourceModel
inherit from Hashable
or trying something like this [protocol<SCResourceModel, Hashable> : String]
obviously does not work as well, since Hashable
or Equatable
can only be used as generic constraints and not as types themselves.
我观看了WWDC 2015,在Swift 2.0中,可以为协议添加约束:协议SCResourceModel其中Self:Hashable {..}
直接解决这个问题(非常好)。
I watched the WWDC 2015 and in Swift 2.0 it is possible to add constraints to a protocol like: protocol SCResourceModel where Self: Hashable {..}
which directly addresses this issue (very nice).
无论如何,我的问题是:可以我使用当前的Swift 1.2版本做了类似的操作,并以某种方式使用该协议作为字典的关键字。或者任何人都可以提出一个很好的解决方法或其他可能忽略的东西?
Anyway, my question is: Can I do something similar with the current Swift 1.2 version and somehow use this protocol as the key of a dictionary? Or can anyone propose a nice workaround or something else that I might have overlooked?
Swift 1.2目前唯一的解决方案是将协议转换为继承自NSObject并且必须被子类化以供我的API进一步使用。
The only solution I see at the moment for Swift 1.2, is to transform the protocol to a class which inherits from e.g. NSObject and must be subclassed for further usage in my API.
感谢您的帮助!
推荐答案
我可能会想方向:
protocol SCResourceModel {
var hashValue: Int { get }
func isEqualTo(another: SCResourceModel) -> Bool
// ...
}
struct SCResourceModelWrapper: Equatable, Hashable {
let model: SCResourceModel
var hashValue: Int {
return model.hashValue ^ "\(model.dynamicType)".hashValue
}
}
func == (lhs: SCResourceModelWrapper, rhs: SCResourceModelWrapper) -> Bool {
return lhs.model.isEqualTo(rhs.model)
}
struct SCResourceModelDictionary<T> {
private var storage = [SCResourceModelWrapper: T]()
subscript(key: SCResourceModel) -> T? {
get {
return storage[SCResourceModelWrapper(model: key)]
}
set {
storage[SCResourceModelWrapper(model: key)] = newValue
}
}
}
这篇关于具有协议类型的Swift字典作为密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!