我有以下协议:

protocol MyProtocol {

    var stringValue: String { get }
}

我还为扩展中的一些类和结构实现了它的方法:
extension Int: MyProtocol {

    var stringValue: String {

        return "IntValue"
    }
}

extension String: MyProtocol {

    var stringValue: String {

        return "StringValue"
    }
}

extension Array: MyProtocol where Element == Dictionary<String, Any> {

    var stringValue: String {

        return "ArrayValue"
    }
}

extension Dictionary: MyProtocol where Key == String, Value == Any {

    var stringValue: String {

        return "DictionaryValue"
    }
}

当我试图用以下代码测试它时:
let dict = [["key":"value"]]
let stringValueResult = dict.stringValue
print(stringValueResult)

我收到一个错误,文本“[[String : String]]不可转换为Array<Dictionary<String, Any>>”。但是,当我像这样设置变量类型dict时,我的代码可以正常工作:
let dict: Array<Dictionary<String, Any>> = [["key":"value"]]

有人能解释一下为什么我的代码的第一个版本没有编译吗?

最佳答案

此错误的原因是编译器推断的dict类型与您在使Array符合您的protocol时提到的类型之间的冲突。
当你写这行的时候

let dict = [["key":"value"]]

对于编译器,当类型Array<Dictionary<String, String>>
let dict: Array<Dictionary<String, String>> = [["key":"value"]]

现在,当您执行dict.stringValue时,编译器将首先将调用对象的类型(即dictArray一致性期间定义的类型)匹配起来
由于编译器推断的类型(即,MyProtocol与一致性中提到的类型(即,Array<Dictionary<String, String>>不同),所以编译器抛出错误。
但是,当您使用显式类型声明Array<Dictionary<String, Any>>变量时,也就是说,dict与根据Array<Dictionary<String, Any>>定义的变量相同时,编译器不会发现任何问题,并且您的代码工作正常。
当您将MyProtocol设置为Array/Dictionary时,您可以忽略如下设置MyProtocol类型,
extension Array: MyProtocol {

    var stringValue: String {

        return "ArrayValue"
    }
}

extension Dictionary: MyProtocol {

    var stringValue: String {

        return "DictionaryValue"
    }
}

关于arrays - 采用数组和字典协议(protocol),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50385471/

10-11 22:09
查看更多