【问题标题】:How to check if value type is Dictionary<String, Any>如何检查值类型是否为 Dictionary<String, Any>
【发布时间】:2017-02-25 21:41:08
【问题描述】:

我在 Swift 中创建了一个循环动态字典的函数,但是当我尝试检查该值是否为 Dictionary 类型时,类型比较条件总是失败,实际上 XCode 会引发以下警告作为提示:

Cast from '(key: String, value: Any)' to unrelated type 'Dictionary<String, Any>' always fails.

我不是要强制转换任何值,我只是想检查变量值是否具有字典类型。

这是我的代码:

    func readNode(node: Dictionary<String, Any>, level: Int)
    {

        // Print spaces
        for _ in 0 ... level
        {
            print(" ")
        }


        for (key, val) in node.enumerated()
        {

            // The following condition is always false (here is the issue)                
            if val is Dictionary<String, Any> {
                print("Key \(key):")
                readNode(node: val, level: (level + 1) * 2)
            }
            else
            {
                print("Key \(key): \(val)")
            }

        }

    }

    var mydict = Dictionary<String, Any>()

    mydict = ["subindex2": 2, "subindex3": 3, "subindex4": ["whatever": "extra"]]

    readNode(node: mydict, level: 0)

我使用的是 Swift 3.0.1。

【问题讨论】:

  • 你为什么在node参数上使用枚举?

标签: swift


【解决方案1】:

enumerated() 从 0 开始创建一个连续的 Ints 序列,并与您调用它的序列的元素配对。这不是你想要的——你只是想遍历给定字典的键值对。所以只需删除.enumerated(),然后直接遍历字典即可。

您还需要使用条件类型转换而不是简单的is 检查,允许在成功分支中将val 静态类型为[String : Any](否则您将无法通过它回到readNode(node:level:))。

// ...

for (key, val) in node {
    if let val = val as? [String : Any] {
        print("Key \(key):")
        readNode(node: val, level: (level + 1) * 2)
    } else {
        print("Key \(key): \(val)")
    }
}

// ...

【讨论】:

  • 感谢 Hamish,所以问题出在 .enumerated。为了学习 Swift,我编写了这段代码作为练习。我不知道没有枚举方法我可以访问字典索引。有点困惑,因为 Apple 手册说:“如果您需要每个项目的整数索引及其值,请使用 enumerated() 方法来迭代数组。对于数组中的每个项目,枚举()”。我知道 Dictionary 不是数组,但是我观察到 Dictionary 类型也存在此方法。
  • @JuanLago 这是对enumerated() 处理集合索引的误解——它只处理从0 开始的简单Int 计数器。对于Array,这只是碰巧 与索引很好地对齐,但其他集合很少出现这种情况。 Dictionary 有一个 Element 类型 (Key, Value) 无论如何(允许您在迭代时访问键和值)。这与您可以使用 Key 下标这一事实相结合,意味着您很少需要使用其实际的 Index 类型(这与它的 Key 顺便说一句完全无关)。
  • 再次感谢您的解释。看来我必须更深入地研究 Swift 才能更好地了解这个小细节。你能给我推荐一些关于 Swift 的书吗?
  • @JuanLago 恐怕我没有任何书籍推荐,但在大多数情况下,语言指南真的很值得学习。
  • 然而,我总是建议查找像 enumerated() in the documentation 这样的方法(这在大多数情况下也很好)。在这种情况下,有一个有用的段落说“枚举集合时,每对的整数部分是枚举的计数器,不一定是配对值的索引。这些计数器只能用作实例中的索引从零开始的整数索引集合,例如 Array 和 ContiguousArray。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
相关资源
最近更新 更多