考虑以下两个协议:
protocol Parser {
associatedtype ResultType
func parse(_ data: Data) throws -> ResultType
}
protocol JSONParser: Parser {
func parse(_ json: [AnyHashable:Any]) throws -> ResultType
}
extension JSONParser {
func parse(_ data: Data) throws -> ResultType {
return try parse([:])
}
}
基本上我们有一个解析数据的基础“原始”解析器,以及一个“增强型”子协议,它将数据解码为字典,并允许符合类型访问解码的JSON。
现在,问题在于类型见证推断不再适用于采用子协议的类型。
这有效:
class RawNumberParser: Parser {
func parse(_ data: Data) throws -> Int {
return data.count
}
}
,因为编译器会自动推断Int
关联类型的类型ResultType
。
但是,以下代码无法编译:
class AdvancedNumberParser: JSONParser {
func parse(_ json: [AnyHashable : Any]) throws -> Int {
return json.count
}
}
错误:类型'AdvancedNumberParser'不符合协议'JSONParser'
明确声明类型别名会使错误消失:
class AdvancedNumberParser: JSONParser {
typealias ResultType = Int
func parse(_ json: [AnyHashable : Any]) throws -> Int {
return json.count
}
}
我是否遗漏了一些声明,或者编译器无法推断子协议的关联类型?
答案 0 :(得分:0)
找到一种解决方法:在子协议中添加关联类型:
protocol JSONParser: Parser {
associatedtype JSONResultType = ResultType
func parse(_ json: [AnyHashable:Any]) throws -> JSONResultType
}
extension JSONParser {
func parse(_ data: Data) throws -> JSONResultType {
return try parse([:])
}
}
由于某种原因,似乎类型见证推断很浅,它只映射当前级别。