我想扩展一个Dictionary方法,但只有当Key的类型为String时才会这样。
我尝试这样做:
extension Dictionary where Key: String {
mutating func lowercaseKeys() {
for key in self.keys {
self[key.lowercase] = self.removeValueForKey(key)
}
}
}
得到错误:
键入'Key'约束为非协议类型'String'
基于此错误消息,我可以告诉我只能使用协议进行此类过滤...有没有办法绕过这个?
答案 0 :(得分:18)
我认为最符合您需求的协议是StringLiteralConvertible
,只需几行,就可以让您完成此任务
extension Dictionary where Key: StringLiteralConvertible {
mutating func setAllKeysLowercase() {
for key in self.keys {
if let lowercaseKey = String(key).lowercaseString as? Key {
self[lowercaseKey] = self.removeValueForKey(key)
}
}
}
}
var stringKeyDictionary = [ "Hello" : NSObject(), "World" : NSObject() ]
stringKeyDictionary.setAllKeysLowercase()
print( stringKeyDictionary )
// Prints: ["hello": <NSObject: 0x1007033c0>, "world": <NSObject: 0x1007033d0>]
var numberKeyDictionary = [ 0 : NSObject(), 1: NSObject() ]
numberKeyDictionary.setAllKeysLowercase() //< Won't compile, keys are not strings
答案 1 :(得分:1)
我已经为Swift 4更新了这个。
extension Dictionary where Key: StringProtocol {
mutating func setAllKeysLowercase() {
for key in self.keys {
if let lowercaseKey = key.lowercased() as? Key {
self[lowercaseKey] = self.removeValue(forKey: key)
}
}
}
}
var stringKeyDictionary = [ "Hello" : 123, "World" : 456 ]
stringKeyDictionary.setAllKeysLowercase()
print( stringKeyDictionary )
打印:["hello": 123, "world": 456]
var numberKeyDictionary = [ 0 : 123, 1: 456 ]
numberKeyDictionary.setAllKeysLowercase()
给出错误:error: cannot use mutating member on immutable value: 'numberKeyDictionary' is immutable
由于StringLiteralConvertible
已被弃用,我认为使用StringProtocol
代替Swift4等效ExpressibleByStringLiteral
可能更好。使用ExpressibleByStringLiteral
表示Key不是String,因此不能使用lowercased
之类的String方法。