以协议类型为键的Swift词典

cro*_*roX 5 macos dictionary protocols ios swift

这里简短的问题:

我得到了一个协议protocol SCResourceModel {..}和一个字典,它将使用这种协议类型作为密钥:[SCResourceModel : String].这显然不起作用,因为字典中的键必须符合协议Hashable.使我SCResourceModel继承Hashable或尝试这样的东西[protocol<SCResourceModel, Hashable> : String]显然不起作用,因为Hashable或者Equatable只能用作通用约束而不是类型本身.

我观看了WWDC 2015和Swift 2.0,可以为协议添加约束,例如:protocol SCResourceModel where Self: Hashable {..}直接解决这个问题(非常好).

无论如何,我的问题是:我可以用当前的Swift 1.2版本做一些类似的东西,并以某种方式使用这个协议作为字典的关键吗?或者任何人都可以提出一个很好的解决方法或其他我可能忽略的东西?

我目前在Swift 1.2中看到的唯一解决方案是将协议转换为继承自例如NSObject的类,并且必须进行子类化以便在我的API中进一步使用.

谢谢你的帮助!

cou*_*elk 5

我可能会想到:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


dil*_*zek 2

好吧,据我所知,没有一种真正好的方法可以将协议本身作为密钥。但我很确定协议名称的字符串版本可以很好地满足您的目的。作为奖励,您还可以将协议对象作为字典中的值(如果这在您的情况下有用)

问题是,我也找不到在 Swift 中做到这一点的好方法,但这是我在 Objective-C 中提出的,也许你会比我更好地找到在 Swift 中做到这一点的方法:

// With a protocol declared...
@protocol TestProtocol <NSObject>
@end

@implementation

// Inside the implementation you can use NSStringFromProtocol()
Protocol *proto = @protocol(TestProtocol);
NSLog(@"Protocol: %@", NSStringFromProtocol(proto));

@end
Run Code Online (Sandbox Code Playgroud)

输出:

Protocol: TestProtocol
Run Code Online (Sandbox Code Playgroud)

@protocol代码的部分是我不太确定如何在 Swift 中执行的部分,如果情况更糟,您始终可以桥接到 Objective-C 文件。希望这能给您一些想法!