【问题标题】:Swift error when trying to access Dictionary: `Could not find member 'subscript'`尝试访问字典时出现 Swift 错误:`找不到成员'下标'`
【发布时间】:2015-09-08 13:21:53
【问题描述】:

这不会编译: 我尝试了几种不同的方法;声明字典的不同方式,更改其类型以匹配数据的嵌套。我还尝试明确说我的Any 是一个集合,因此它可以下标。没有骰子。

import UIKit


import Foundation

class CurrencyManager {

    var response = Dictionary<String,Any>()
    var symbols = []


    struct Static {
        static var token : dispatch_once_t = 0
        static var instance : CurrencyManager?
    }

    class var shared: CurrencyManager {
        dispatch_once(&Static.token) {  Static.instance = CurrencyManager() }
        return Static.instance!
    }

    init(){
        assert(Static.instance == nil, "Singleton already initialized!")
        getRates()

    }


    func defaultCurrency() -> String {

        let countryCode  = NSLocale.currentLocale().objectForKey(NSLocaleCountryCode) as String
        let codesToCountries :Dictionary = [ "US":"USD" ]

        if let localCurrency = codesToCountries[countryCode]{
            return localCurrency
        }

        return "USD"

    }

    func updateBadgeCurrency() {

        let chanCurr = defaultCurrency()

        var currVal :Float = valueForCurrency(chanCurr, exchange: "Coinbase")!

        UIApplication.sharedApplication().applicationIconBadgeNumber = Int(currVal)

    }

    func getRates() {
        //Network code here
        valueForCurrency("", exchange: "")
    }

    func valueForCurrency(currency :String, exchange :String) -> Float? {
        return response["current_rates"][exchange][currency] as Float
    }


}

【问题讨论】:

    标签: swift


    【解决方案1】:

    我们来看看

    response["current_rates"][exchange][currency]
    

    response 被声明为Dictionary&lt;String,Any&gt;(),因此在第一个下标之后,您尝试在 Any 类型的对象上调用另外两个下标。

    解决方案 1. 将响应类型更改为嵌套字典。请注意,我添加了问号,因为每当您访问字典项目时,您都会得到一个可选的。

    var response = Dictionary<String,Dictionary<String,Dictionary<String, Float>>>()
    
    func valueForCurrency(currency :String, exchange :String) -> Float? {
        return response["current_rates"]?[exchange]?[currency]
    }
    

    解决方案 2. 在解析时将每个级别转换为字典。确保仍然检查可选值是否存在。

    var response = Dictionary<String,Any>()
    
    func valueForCurrency(currency :String, exchange :String) -> Float? {
        let exchanges = response["current_rates"] as? Dictionary<String,Any>
    
        let currencies = exchanges?[exchange] as? Dictionary<String,Any>
    
        return currencies?[currency] as? Float
    }
    

    【讨论】:

    • 这不起作用的任何原因? let exchanges = response["current_rates"] as Dictionary?
    • 我得到“找不到接受提供的参数的下标的重载”
    • 我添加了第二个解决方案。要使用该方法,您只需将问号放在“as”之后而不是“Dictionary”之后
    • 没有硬编码嵌套类型的任何方式吗? (即我对亚历克斯回答的评论)
    • 只需添加元素类型:let symbols = response["symbols"] as? Array&lt;ElementType&gt;
    【解决方案2】:

    您可以按照以下步骤获取嵌套字典数据:

    let imageData: NSDictionary = userInfo["picture"]?["data"]? as NSDictionary
    let profilePic = imageData["url"] as? String
    

    【讨论】:

      【解决方案3】:
      func valueForCurrency(currency :String, exchange :String) -> Float? {
          if let exchanges = response["current_rates"] as? Dictionary<String,Any> {
              if let currencies = exchanges[exchange] as? Dictionary<String,Any> {
                  return currencies[currency] as? Float
              }
          }
          return nil
      }
      

      【讨论】:

        【解决方案4】:

        response 是这样声明的:

        var response = Dictionary<String,Any>()
        

        因此编译器认为response["current_rates"] 将返回Any。这可能是也可能不是可下标索引的东西。

        您应该能够使用嵌套字典定义您的类型,3 个级别,最终您会得到一个浮点数。您还需要使用可选链接进行深入研究,因为字典可能有也可能没有该键的值,因此它的下标访问器返回一个可选的。

        var response = Dictionary<String,Dictionary<String,Dictionary<String,Float>>>()
        // ... populate dictionaries
        println(response["current_rates"]?["a"]?["b"]) // The float
        

        【讨论】:

        • 问题不在于整个层次结构中的所有对象都遵循这些泛型。某处可能有一个数组,我不想在这段代码中对 JSON 的整个解释进行硬编码。
        • 那么你需要在运行时检查类型和强制转换。
        • 问题是,我知道我想要的元素的具体类型,我想忽略其他的。如果我访问 ["current_rates"],我知道我会总是得到一本字典。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 2015-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多