【问题标题】:Type inference for associated type doesn't work in child protocol关联类型的类型推断在子协议中不起作用
【发布时间】:2018-02-14 14:42:16
【问题描述】:

考虑以下两种协议:

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

,因为编译器会自动为 ResultType 关联类型推断类型 Int

但是,以下代码无法编译:

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

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

【问题讨论】:

    标签: swift protocols type-inference


    【解决方案1】:

    找到解决方法:在子协议中添加关联类型:

    protocol JSONParser: Parser {
        associatedtype JSONResultType = ResultType
    
        func parse(_ json: [AnyHashable:Any]) throws -> JSONResultType
    }
    
    extension JSONParser {
        func parse(_ data: Data) throws -> JSONResultType {
            return try parse([:])
        }
    }
    

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

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多