xcode 使用 Swift 创建字典作为可选属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25126929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:19:41  来源:igfitidea点击:

Create a Dictionary as a optional property using Swift

iosxcodeswift

提问by Sebastian

I created a swift class to test Dictionaries. So, I wrote the code below:

我创建了一个 swift 类来测试字典。所以,我写了下面的代码:

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":

所以,我收到了 3 个关于“myThirdDictionary”的错误:

  • In the Dictionary initialization compiler said: Could not find an overload for 'init' that accepts the supplied arguments
  • When I tried to add a Key/value pair in addOneThingToThirdDictionary(): '[String : String]?' does not have a member named 'subscript'
  • When I tried to add a Key/value pair in addAnotherThingToThirdDictionary(): Immutable value of type '[String : String]' only has mutating members named 'updateValue'
  • 在字典初始化编译器中说:找不到接受提供的参数的“init”的重载
  • 当我尝试在addOneThingToThirdDictionary() 中添加键/值对时:'[String : String]?' 没有名为“下标”的成员
  • 当我尝试在addAnotherThingToThirdDictionary() 中添加键/值对时: “[String : String]”类型的不可变值只有名为“updateValue”的变异成员

Any thoughts ?

有什么想法吗 ?

采纳答案by rickster

Some of these issues are conceptual errors, and some of them have to do with behaviors that changed in today's Xcode 6 beta 5 release. Running through them all:

其中一些问题是概念性错误,其中一些与今天的 Xcode 6 beta 5 版本中更改的行为有关。贯穿它们:

  • This line compiles, but has a superfluous !:

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

    You don't need to unwrap an optional to assign to it -- it doesn't matter if its current contents are nilif you're providing new contents. Instead, just assign:

    self.myThirdDictionary = [String :String]()
    
  • Similarly, this line fails because you're subscripting before unwrapping:

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

    This is a problem because you could be subscripting nilif myThirdDictionaryhas not been initialized. Instead, subscript after checking/unwrapping the optional. As of beta 5, you can use mutating operators or methods through an optional check/unwrap, so the shortest and safest way to do this is:

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

    If myThirdDictionaryis nil, this line has no effect. If myThirdDictionaryhas been initialized, the subscript-set operation succeeds.

  • This line failed on previous betas because force-unwrapping produced an immutable value:

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

    Now, it works -- sort of -- because you can mutate the result of a force-unwrap. However, force unwrapping will crash if the optional is nil. Instead, it's better to use the optional-chaining operator (which, again, you can now mutate through):

    self.myThirdDictionary?.updateValue("Superman", forKey: "hero")
    
  • 这一行可以编译,但有一个多余的!

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

    你不需要解开一个可选项来分配给它——nil如果你提供新的内容,它的当前内容是否无关紧要。相反,只需分配:

    self.myThirdDictionary = [String :String]()
    
  • 同样,此行失败,因为您在解包之前添加了下标:

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

    这是一个问题,因为nil如果myThirdDictionary尚未初始化,您可能正在下标。相反,在检查/解开可选项后下标。从 beta 5 开始,您可以通过可选的检查/解包来使用变异运算符或方法,因此执行此操作的最短和最安全的方法是:

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

    如果myThirdDictionarynil,则此行无效。如果myThirdDictionary已经初始化,则下标集操作成功。

  • 这一行在之前的测试版上失败了,因为强制展开产生了一个不可变的值:

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

    现在,它起作用了——有点——因为你可以改变强制解包的结果。但是,如果可选项为 ,则强制展开将崩溃nil。相反,最好使用可选链运算符(同样,您现在可以通过它进行变异):

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

Finally, you have a lot of things in this code that can be slimmed down due to type and scope inference. Here it is with all the issues fixed and superfluous bits 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: Foundationimport unused, empty dictionary literal instead of repeated type info)

(更改:Foundation导入未使用的空字典文字而不是重复的类型信息)

回答by Zain Shahzad

Simple but effective

简单但有效

let like = (dic.value(forKey: "likes") as? NSDictionary)
print(like?.count)

Or if you want get complete Dictionary count then use:

或者,如果您想获得完整的字典计数,请使用:

 if let mainDic = dic as? NSDictionary{ 
    print(mainDic.count) 
    //add your code
}