具有协议类型的Swift字典作为密钥 [英] Swift Dictionary with Protocol Type as Key

查看:131
本文介绍了具有协议类型的Swift字典作为密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简单的问题在这里:

我得到一个协议协议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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆