2015-10-16 35 views
12

我想擴展Dictionary的方法,但只有當Key是String類型的時候。Extend Dictionary Key其中字符串類型是字符串

我嘗試這樣做:

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'

基於此錯誤信息,我可以告訴大家,我只能做這樣的與協議過濾的...是有沒有辦法繞過這個?

回答

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 
+5

StringLiteralConvertible從Swift開始已棄用3.使用ExpressibleByStringLiteral代替。 –

+0

很高興知道,謝謝@MacBellingrath! –

0

我已經更新了本作斯威夫特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

相關問題