【问题标题】:Swift 3: Cant unwrap optional from Dictionary?Swift 3:不能从字典中解开可选?
【发布时间】:2016-12-29 17:35:44
【问题描述】:

好吧,我不知道这里发生了什么。我在下面有一个字符串字典:

var animals = ["max": "z", "Royal": nil] //store key pairs

如果不打印“可选”,我将无法打印键值对中的值的值。

我尝试过使用 ! !! 并转换为字符串以及以下内容:

var animalsToReturn = [String]()

        if animals[selected]! != nil
        {
            if let pairName = animals[selected]
            {
                print("\(pairName)")

                print("has pair",selected, animals[selected]!)

//trying to append to another array here
                animalsToReturn.append("\(animals[selected]!)")
                animalsToReturn.append(selected)
            }
        }
        else {
            print("no pair")
        }

我检查以确保该值不为零,因此如果我打开它不会崩溃。但这就是打印的内容,并且 Optional 这个词被附加到我的另一个数组中:

【问题讨论】:

  • 字典中的显式nil 值是无稽之谈,因为nil 值意味着缺少键,根据定义,您可以通过分配nil 来删除键。
  • 您有一个字典,其值为Optional<String>,因为您将nil 存储为一个值。因此,当您没有得到nil 时,您必须双重展开,而且正如vadian 所说,您遇到了nil 已经是未找到标记的困难。如果是nil,最好不要将其存储在字典中!顺便说一句,Apple 有一篇关于这个主题的非常好的博客文章:developer.apple.com/swift/blog/?id=12 这讨论了如何制作不同的未找到标记。

标签: ios swift swift3 optional


【解决方案1】:

您已将nil 作为值包含在内,因此您的字典值的类型不是字符串而是Optional<String>。但是从字典中按键获取值本身就是一个可选的。因此:

  • 如果您的条目存在并且最终是一个字符串,则它是一个Optional<Optional<String>>,您必须将其解包两次。

  • 如果您的条目存在并且最终为nil,则它是一个可选包装nil

  • 如果您的条目不存在,则为nil

您可以按如下方式轻松测试:

func test(_ selected:String) {
    var animals = ["max": "z", "Royal": nil]
    if let entry = animals[selected] { // attempt to find
        if let entry = entry { // attempt to double-unwrap
            print("found", entry)
        } else {
            print("found nil")
        }
    } else {
        print("not found")
    }
}
test("max") // found z
test("Royal") // found nil
test("glop") // not found

考虑该示例将回答您最初的问题,即“我不知道这里发生了什么”。

【讨论】:

    【解决方案2】:

    animals[selected] 是一个Optional<Optional<String>>,因为您正在存储nil。你可以:

    1. 使用if let! 两次打开您的值。
    2. 将字典的类型更改为[String: String](而不是[String: String?]),从而避免使用nil 值。
    3. 展平字典,删除nil 值,然后将其作为[String: String] 访问

    您可以使用this question 中的代码来展平字典。

    【讨论】:

      【解决方案3】:

      请将其括在括号中并使用双重展开。试试这个:-

      animalsToReturn.append("\((animals[selected])!!)")
      

      【讨论】:

        【解决方案4】:
        func addAnimal(_ animal: String) {
            guard let animal = animals[animal] else {
                print("No pair")
                return
            }
            animalsToReturn.append(animal ?? "")
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-05
          • 1970-01-01
          • 1970-01-01
          • 2017-04-27
          相关资源
          最近更新 更多