基於字符串的枚舉我想延長Dictionary
與String
鍵(JSON字典),以允許與一個具有RawValue
類型的String
任何enum
下標。最終目標是多個enums
,可用於標記JSON字典。標字典與夫特
enum JSONKey: String {
case one, two, three
}
enum OtherJSONKey: String {
case a, b, c
}
if let one = jsonDictionary[.one] { /* ... */ }
if let b = jsonDictionary[.b] { /* ... */ }
但我無法弄清楚如何實現這一點。我知道我需要擴展Dictionary
,但無法弄清楚通用擴展約束或方法擴展約束。
我的第一個想法是儘量通用約束添加到標方法。但我不認爲下標方法允許泛型。
extension Dictionary {
subscript<T: RawRepresentable>(key: T) -> Value? { /* ... */ }
}
即使將下標的通用約束工作,我仍然需要一種方法來嵌套我的通用約束。或者將字典限制爲基於字符串的枚舉鍵。爲了把它的代碼是無效的,我想這樣做:
extension Dictionary where Key: RawRepresentable where RawValue == String {
subscript(key: Key) -> Value { /* ... */ }
}
// or
extension Dictionary {
subscript<T: RawRepresentable where RawValue == String>(key: T) -> Value { /* ... */ }
}
正在擴大Dictionary
接受基於字符串的枚舉作爲實際上可能標?
我對如何實現這樣的東西的其他想法包括enum
繼承和創建一個特定的enums
協議,我想用作下標。我知道其中一些做不了,但認爲值得一提的是這個想法。所以,再次把它的代碼是無效的:
enum JSONKey: String {}
enum NumbersJSONKey: JSONKey {
case one, two, three
}
enum LettersJSONKey: JSONKey {
case a, b, c
}
// or
protocol JSONKeys {}
enum NumbersJSONKey: JSONKey {
case one, two, three
}
enum LettersJSONKey: JSONKey {
case a, b, c
}
// then subscript with
if let one = json[.one] { /* ... */ }
更新:
我打這個多一些,並得到一點點接近。下面的擴展名編譯,但如果我真的嘗試使用它,會給我一個「下標不明確」的錯誤。
extension Collection where Iterator.Element == (key: String, value: AnyObject) {
// Compiles but can't be used because of ambiguous subscript.
subscript(key: CustomStringConvertible) -> AnyObject? {
guard let i = index(where: { $0.key == key.description }) else { return nil }
return self[i].value
}
}
@ titaniumdecoy的回答工作所以這將是公認的答案,除非有人能想出更好的東西。
在'[String:String]'字典中,您將無法使用'.one'對其進行下標。您必須使用'JSONKey.one'來執行此操作(除了您要求的擴展外)。 – WMios
這仍然很好。這允許使用JSON鍵的名稱空間而不是鍵入'json [「someKey」]或保留一堆'String'常量。 – keithbhunter
想通了。看看我的答案。 – WMios