在Swift中获取错误对成员'下标'的模糊引用

时间:2016-11-02 10:10:56

标签: swift dictionary swift3

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

在下面的代码中实现并成功编译:

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

但是当我在方法上做了一些小改动时得到错误:

  

&#34;对成员&#39;下标&#39;的模棱两可的提及&#34;

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

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

2 个答案:

答案 0 :(得分:5)

尝试将keyValue投射到密钥。例如:

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

答案 1 :(得分:1)

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

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

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

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"] ?? ""
  }
}

作为旁注,可能值得使返回语句更清晰,更容易调试:

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
  }
}