采用数组和字典的协议
Adopt a protocol for Array and Dictionary
我有以下协议:
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"]]
谁能解释一下为什么我的第一个版本的代码无法编译?
您应该像这样更改 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)
此错误的原因是编译器推断的 dict
类型与您在 Array
符合 protocol
时提到的类型之间存在冲突。
写这行的时候
let dict = [["key":"value"]]
对于编译器,它将变成如下类型为 Array<Dictionary<String, String>>
let dict: Array<Dictionary<String, String>> = [["key":"value"]]
现在,当您执行 dict.stringValue
时,编译器将首先匹配调用对象的类型,即 dict
与您在 Array
与 [=20= 的一致性期间定义的类型]
由于编译器推断类型,即 Array<Dictionary<String, String>>
不同于您在一致性中提到的类型,即 Array<Dictionary<String, Any>>
,因此编译器会抛出错误。
但是当您声明 dict
具有显式类型的变量时,即 Array<Dictionary<String, Any>>
与您根据 MyProtocol
定义的相同,那么编译器看不到任何问题并且您的代码工作正常.
虽然 Array/Dictionary
符合 MyProtocol
,但您可以忽略设置 Element
类型,如下所示,
extension Array: MyProtocol {
var stringValue: String {
return "ArrayValue"
}
}
extension Dictionary: MyProtocol {
var stringValue: String {
return "DictionaryValue"
}
}
我有以下协议:
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"]]
谁能解释一下为什么我的第一个版本的代码无法编译?
您应该像这样更改 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)
此错误的原因是编译器推断的 dict
类型与您在 Array
符合 protocol
时提到的类型之间存在冲突。
写这行的时候
let dict = [["key":"value"]]
对于编译器,它将变成如下类型为 Array<Dictionary<String, String>>
let dict: Array<Dictionary<String, String>> = [["key":"value"]]
现在,当您执行 dict.stringValue
时,编译器将首先匹配调用对象的类型,即 dict
与您在 Array
与 [=20= 的一致性期间定义的类型]
由于编译器推断类型,即 Array<Dictionary<String, String>>
不同于您在一致性中提到的类型,即 Array<Dictionary<String, Any>>
,因此编译器会抛出错误。
但是当您声明 dict
具有显式类型的变量时,即 Array<Dictionary<String, Any>>
与您根据 MyProtocol
定义的相同,那么编译器看不到任何问题并且您的代码工作正常.
虽然 Array/Dictionary
符合 MyProtocol
,但您可以忽略设置 Element
类型,如下所示,
extension Array: MyProtocol {
var stringValue: String {
return "ArrayValue"
}
}
extension Dictionary: MyProtocol {
var stringValue: String {
return "DictionaryValue"
}
}