扩展 Dictionary,其中 Key 是 String 类型
Extend Dictionary where Key is of type String
我想扩展 Dictionary 的方法,但前提是 Key 是 String 类型。
我尝试这样做:
extension Dictionary where Key: String {
mutating func lowercaseKeys() {
for key in self.keys {
self[key.lowercase] = self.removeValueForKey(key)
}
}
}
并得到错误:
Type 'Key' constrained to non-protocol type 'String'
根据这个错误消息,我可以知道我只能使用协议进行这种过滤...有没有办法绕过这个?
我相信最能满足您需求的协议是 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
我已经为 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
意味着键不是字符串,因此不能使用像 lowercased
.
这样的字符串方法
我想扩展 Dictionary 的方法,但前提是 Key 是 String 类型。
我尝试这样做:
extension Dictionary where Key: String {
mutating func lowercaseKeys() {
for key in self.keys {
self[key.lowercase] = self.removeValueForKey(key)
}
}
}
并得到错误:
Type 'Key' constrained to non-protocol type 'String'
根据这个错误消息,我可以知道我只能使用协议进行这种过滤...有没有办法绕过这个?
我相信最能满足您需求的协议是 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
我已经为 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
意味着键不是字符串,因此不能使用像 lowercased
.