【问题标题】:In Swift getting error Ambiguous reference to member 'subscript'在 Swift 中出现错误对成员“下标”的模糊引用
【发布时间】:2016-11-02 10:10:55
【问题描述】:

Dictionary 的必需扩展,以获取文本键值(如果存在)。

实现如下代码,编译成功:

extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
    func getValueForKeyPath(keyValue: String) -> String {
        return ((self["item_qty"] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
    }
}

但是当我对方法进行小改动时,出现以下错误:

"对成员'下标'的模糊引用"

extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
    func getValueForKeyPath(keyValue: String) -> String {
        return ((self[keyValue] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
    }
}

如果我在这里做错了什么,请纠正我。

【问题讨论】:

    标签: swift dictionary swift3


    【解决方案1】:

    尝试将keyValue 转换为。例如:

    extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject {
        func getValueForKeyPath(keyValue : String) -> String{
            return ((self[keyValue as! Key] as? Dictionary<String,String>) ?? ["":""])?["text"] ?? ""
        }
    }
    

    【讨论】:

      【解决方案2】:

      虽然@Hoa 的答案可以编译,但它会在某些情况下崩溃(即当Dictionary.Key 不是String 时)。

      更好的解决方案可能是使用来自ExpressibleByStringLiteral 协议的init(...) 方法之一。

      注意额外的通用约束: Key.StringLiteralType == String。这允许我们使用keyValue 来实例化Key 对象,然后在self[key] 中使用that
      我认为我们可以假设几乎所有使用的字符串都是@987654329 @,所以这应该不会影响任何事情。

      extension Dictionary where Key: ExpressibleByStringLiteral,
        Key.StringLiteralType == String,
        Value: AnyObject {
      
        func getValueForKeyPath(keyValue: String) -> String {
          let key = Key(stringLiteral: keyValue) // <-- this is key
      
          return ((self[key] as? Dictionary<String, String>) ?? ["": ""])?["text"] ?? ""
        }
      }
      

      附带说明一下,让 return 语句更清晰、更易于调试可能是值得的:

      extension Dictionary where Key: ExpressibleByStringLiteral,
        Key.StringLiteralType == String,
        Value: AnyObject {
      
        func getValueForKeyPath(keyValue: String) -> String {
          let key = Key(stringLiteral: keyValue)
      
          guard let dict = self[key] as? Dictionary<String, String>,
            let text = dict["text"]
            else {
              return ""
          }
      
          return text
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-05-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-22
        • 1970-01-01
        • 2017-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多