关联类型的类型推断在子协议

时间:2018-02-14 14:42:16

标签: swift protocols type-inference

考虑以下两个协议:

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
    }
}

我是否遗漏了一些声明,或者编译器无法推断子协议的关联类型?

1 个答案:

答案 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([:])
    }
}

由于某种原因,似乎类型见证推断很浅,它只映射当前级别。