2015-06-17 80 views
3

短的問題在這裏:斯威夫特字典與協議類型爲重點

我得到了一個協議protocol SCResourceModel {..}並須使用該協議類型爲重點的字典:[SCResourceModel : String]。 這顯然不起作用,因爲字典中的關鍵字必須符合協議Hashable。讓我的SCResourceModel繼承自Hashable或嘗試像這樣[protocol<SCResourceModel, Hashable> : String]顯然不能正常工作,因爲HashableEquatable只能用作通用約束,而不能用作類型本身。

我觀看了WWDC 2015,並且在Swift 2.0中可以添加約束條件,如:protocol SCResourceModel where Self: Hashable {..}直接解決此問題(非常好)。

無論如何,我的問題是:我可以做一些類似於當前的Swift 1.2版本,並以某種方式使用此協議作爲字典的關鍵?或者任何人都可以提出一個很好的解決方法或其他我可能忽略的東西?

我目前在Swift 1.2中看到的唯一解決方案是將協議轉換爲繼承自例如NSObject,並且必須在我的API中進一步使用。

感謝您的幫助!

+0

你大概的意思雨燕1.2,沒有1.3。它應該像'protocol SCResourceModel:Hashable {}一樣工作嗎?或者你有錯誤嗎?如果是這樣,顯示你的(最小)代碼 – Kametrixom

+0

我修正了這個版本:)你的建議不起作用,因爲這使'SCResourceModel'成爲'Hashable'類型。不允許將它僅用作泛型約束(它也不會編譯)。代碼幾乎已經在問題中了。協議和字典,兩行。如果您有其他問題,請告訴我。 – croX

回答

2

好吧,據我所知,沒有一種非常好的方法可以將協議本身作爲關鍵。但我很確定協議名稱的字符串版本可以很好地滿足您的需求。作爲獎勵,你也可以將協議對象作爲字典中的值(如果這在你的情況下是有用的)

事情是,我找不到在Swift中這樣做的好方法,但這裏是我已經在Objective-C想出了,也許你也能找到一種方法比我更好地做到這一點斯威夫特:

// 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 

輸出:

Protocol: TestProtocol 

的是,@protocol部分代碼是我不確定如何在Swift中做的部分,如果情況更糟糕,你可以alwa y橋接到Objective-C文件。希望這給你一些想法!

+0

感謝您的想法 – croX

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 
     } 
    } 
} 
+0

很好的解決方法來創建自定義字典。我喜歡! – croX