我有以下协议:
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"]]
有人可以解释为什么我的代码的第一个版本没有编译吗?
答案 0 :(得分:1)
您应该更改Array
和Dictionary
实施约束,如下所示:
extension Array: MyProtocol where Element: MyProtocol {
var stringValue: String {
return "ArrayValue"
}
}
extension Dictionary: MyProtocol where Key == String {
var stringValue: String {
return "DictionaryValue"
}
}
现在,如果您运行以下代码,则会打印:ArrayValue
let dict = [["key":"value"]]
let stringValueResult = dict.stringValue
print(stringValueResult)
答案 1 :(得分:0)
此错误的原因是编译器推断的dict
类型与您在Array
符合protocol
时提到的类型之间的冲突。
当你写这行时
let dict = [["key":"value"]]
对于编译器,它将变为如下类型Array<Dictionary<String, String>>
let dict: Array<Dictionary<String, String>> = [["key":"value"]]
现在,当您执行dict.stringValue
时,编译器将首先匹配调用对象的类型,即dict
与您在Array
与MyProtocol
<的一致性期间定义的类型/ p>
由于编译器推断类型,即Array<Dictionary<String, String>>
与您在一致性中提到的类型不同,即Array<Dictionary<String, Any>>
,因此编译器会抛出错误。
但是当您使用显式类型声明dict
变量时,Array<Dictionary<String, Any>>
与您在MyProtocol
的一致性中定义的相同,那么编译器看不到任何问题,并且您的代码工作正常。< / p>
在Array/Dictionary
符合MyProtocol
的同时,您可以忽略设置Element
类型,如下所示
extension Array: MyProtocol {
var stringValue: String {
return "ArrayValue"
}
}
extension Dictionary: MyProtocol {
var stringValue: String {
return "DictionaryValue"
}
}