swift - Using an enum's default value as a dictionary key without explicitly casting to String -


if declare enum this:

enum keys {     case key_one     case key_two } 

i can print , automatically converted string:

print(keys.key_one) // prints "key_one" 

if make dictionary maps strings whatever (but let's choose strings again simplicity), think should able add key using keys.key_one key, right? wrong.

var mydict = [string : string]()  /// error: cannot subscript value of type '[string : string]' index /// of type 'keys' mydict[keys.key_one] = "firstkey" 

i can if explicitly convert keys.key_one string though:

mydict[string(keys.key_one)] = "firstkey" print(mydict) // ["key_one": "firstkey"] 

so want without having wrap enum string() every time.

i've tried few things doing extension off of dictionary using where keyword key , trying implement new subscript functions, can't work. what's trick?

update solution

i found solution (see below).

i figured out extension solution wanted.

extension dictionary {      subscript(key: keys) -> value? {         {             return self[string(key) as! key]         }         set(value) {             guard                 let value = value else {                     self.removevalueforkey(string(key) as! key)                     return             }              self.updatevalue(value, forkey: string(key) as! key)         }     }  }  enum keys {     case key_one     case key_two }  var mystringdict = [string : string]() /// adding first key value through string() way on purpose mystringdict.updatevalue("firstvalue", forkey: string(keys.key_one)) // mystringdict: ["key_one": "firstvalue"] // mystringdict[keys.key_one]!: firstvalue  mystringdict[keys.key_two] = "secondvalue" // mystringdict: ["key_one": "firstvalue", "key_two": "secondvalue"]  mystringdict[keys.key_one] = nil // mystringdict: ["key_two": "secondvalue"] 

notice declared dictionary key type string, i'm able use keys.key_one , subscript in dictionary extension takes care of rest.

i can put better guarding around as! conversion key, i'm not sure it's needed, know enum can converted valid key string() cast.

improvement answer

even better, since i'm using api keys, made blank protocol called apikeys , each model implement own keys enum conforms apikeys protocol. , dictionary's subscript updated take in apikeys key value.

extension dictionary {      subscript(key: apikeys) -> value? {         {             return self[string(key) as! key]         }         set(value) {             guard                 let value = value else {                     self.removevalueforkey(string(key) as! key)                     return             }              self.updatevalue(value, forkey: string(key) as! key)         }     }  }  protocol apikeys {}  enum keys: apikeys {     case key_one     case key_two }  enum model1keys: apikeys {     case model_1_key_one     case model_1_key_two }  enum model2keys: apikeys {     case model_2_key_one     case model_2_key_two }  var mystringdict = [string : string]() var model1stringdict = [string : string]() var model2stringdict = [string : string]()  mystringdict.updatevalue("firstvalue", forkey: string(keys.key_one))    // mystringdict: ["key_one": "firstvalue"] mystringdict[keys.key_two] = "secondvalue"                              // mystringdict: ["key_one": "firstvalue", "key_two": "secondvalue"] mystringdict[keys.key_one] = nil                                        // mystringdict: ["key_two": "secondvalue"]  model1stringdict.updatevalue("firstvalue", forkey: string(model1keys.model_1_key_one))  // model1stringdict: ["model_1_key_one": "firstvalue"] model1stringdict[model1keys.model_1_key_two] = "secondvalue"                            // model1stringdict: ["model_1_key_one": "firstvalue", "model_1_key_two": "secondvalue"] model1stringdict[model1keys.model_1_key_one] = nil                                      // model1stringdict: ["model_1_key_two": "secondvalue"]  model2stringdict.updatevalue("firstvalue", forkey: string(model2keys.model_2_key_one))  // model2stringdict: ["model_2_key_one": "firstvalue"] model2stringdict[model2keys.model_2_key_two] = "secondvalue"                            // model2stringdict: ["model_2_key_one": "firstvalue", "model_2_key_two": "secondvalue"] model2stringdict[model2keys.model_2_key_one] = nil                                      // model2stringdict: ["model_2_key_two": "secondvalue"] 

Comments

Popular posts from this blog

gridview - Yii2 DataPorivider $totalSum for a column -

java - Suppress Jboss version details from HTTP error response -

Sass watch command compiles .scss files before full sftp upload -