我有以下协议:
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
时,编译器将首先将调用对象的类型(即dict
与Array
一致性期间定义的类型)匹配起来由于编译器推断的类型(即,
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/