Create a dictionary as an optional property with Swift

I created a quick class for testing Dictionaries. So, I wrote the code below:

import Foundation

   class MyClass {

    var myFirstDictionary:[String :String]
    var myThirdDictionary:[String :String]?

    init(){
        var mySecondDictionary:[String :String] = [String :String]()
        mySecondDictionary["animal"] = "Monkey"
        mySecondDictionary.updateValue("something", forKey: "SomeKey")

        self.myFirstDictionary = [String :String]()
        addOneThingToSecondDictionary()
        addAnotherThingToSecondDictionary()

        self.myThirdDictionary! = [String :String]()
        addOneThingToThirdDictionary()
        addAnotherThingToThirdDictionary()
    }

    func addOneThingToSecondDictionary(){
        self.myFirstDictionary["animal"] = "Monkey"
    }

    func addAnotherThingToSecondDictionary(){
        self.myFirstDictionary.updateValue("Superman", forKey: "hero")
    }

    func addOneThingToThirdDictionary(){
        self.myThirdDictionary["animal"]! = "Monkey"
    }

    func addAnotherThingToThirdDictionary(){
        self.myThirdDictionary!.updateValue("Superman", forKey: "hero")
    }

  }

      

So I got 3 errors referring to "myThirdDictionary":

  • In the initialization of the dictionary, the compiler said: Could not find an overload for 'init' that takes the supplied arguments
  • When did I try to add a key / value pair to addOneThingToThirdDictionary () : '[String: String]? doesn't have a member named 'subscript'
  • When I tried to add a key / value pair to addAnotherThingToThirdDictionary () : the immutable value of type '[String: String]' only has mutating elements named 'updateValue'

Any thoughts?

+3


source to share


1 answer


Some of these issues are conceptual errors, and some of them are related to behavior that changed in today's release of Xcode 6 beta 5. Doing all of them:

  • This line compiles but has redundant !

    :

    self.myThirdDictionary! = [String :String]()
    
          

    You don't need to expand the optional parameter to assign it - it doesn't matter if its the current content nil

    as long as you provide new content. Instead, just assign:

    self.myThirdDictionary = [String :String]()
    
          

  • Likewise, this line fails because you are signing the subscription before unpacking:

    self.myThirdDictionary["animal"]! = "Monkey"
    
          

    This is a problem because you might be signing nil

    if myThirdDictionary

    it was not initialized. Instead, the index after checking / expanding the optional. Since beta 5, you can use mutating operators or methods with optional validation / unpacking, so the shortest and safest way to do it is:

    self.myThirdDictionary?["animal"] = "Monkey"
    
          

    If myThirdDictionary

    - nil

    , this line has no effect. If initialized myThirdDictionary

    , the indexing operation succeeds.

  • This line failed in previous beta releases because forced deployment produced an immutable value:

    self.myThirdDictionary!.updateValue("Superman", forKey: "hero")
    
          

    Now it works - sort of - because you can mutate the result of a forced reversal. However, force deployment will abort if option nil

    . It's better to use the optional chaining operator instead (which, again, you can mutate now):

    self.myThirdDictionary?.updateValue("Superman", forKey: "hero")
    
          

Finally, there are many things in this code that can be ironed out due to the type and scope inference. Here all the problems have been fixed and the extra bits have been removed:



class MyClass {

    var myFirstDictionary: [String: String]
    var myThirdDictionary: [String: String]?

    init(){
        var mySecondDictionary: [String: String] = [:]
        mySecondDictionary["animal"] = "Monkey"
        mySecondDictionary.updateValue("something", forKey: "SomeKey")

        myFirstDictionary = [:]
        addOneThingToSecondDictionary()
        addAnotherThingToSecondDictionary()

        // uncomment to see what happens when nil
        myThirdDictionary = [:]
        addOneThingToThirdDictionary()
        addAnotherThingToThirdDictionary()
    }

    func addOneThingToSecondDictionary(){
        myFirstDictionary["animal"] = "Monkey"
    }

    func addAnotherThingToSecondDictionary(){
        myFirstDictionary.updateValue("Superman", forKey: "hero")
    }

    func addOneThingToThirdDictionary(){
        myThirdDictionary?["animal"] = "Monkey"
    }

    func addAnotherThingToThirdDictionary(){
        myThirdDictionary?.updateValue("Superman", forKey: "hero")
    }

}

      

(Changes: Foundation

Import unused, empty dictionary literal instead of duplicate type information)

+2


source







All Articles