Swift 符合更具体的协议扩展版本

Swift 符合更具体的协议扩展版本,swift,protocols,Swift,Protocols,假设有一个空协议来限制类型: public protocol DataType { } protocol Parser { func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T } 因此,如果我们为此实现一个manager类: class JSONParsingManager: JSONParser { public var jsonDecoder: JSONDecoder

假设有一个空协议来限制类型:

public protocol DataType { }

protocol Parser {
    func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T
}
因此,如果我们为此实现一个manager类:

class JSONParsingManager: JSONParser {
    public var jsonDecoder: JSONDecoder

    init(jsonDecoder: JSONDecoder) {
        self.jsonDecoder = jsonDecoder
    }
}
Expect会自动运行,但会抛出:

类型“JSONParsingManager”不符合协议“Parser”

我错过了什么?我需要为其他序列化程序(如Protobuf解析器等)定义管理器,所以我不能一开始就遵循Decodable

更明确的是:

另一个应以相同方式工作的协议:

protocol ProtobufParser: Parser {
    func parseData<T: Message>(_ data: Data, to: T.Type) throws -> T
}

extension ProtobufParser {
    func parseData<T: Message>(_ data: Data, to: T.Type) throws -> T { try T.init(serializedData: data) }
}
更新: 我不能定义独立的协议,因为有一个函数需要任何类型的解析器来解析任何可解析的对象


另外,这个问题以前可能是用不同的标题和场景提出的。如果您知道该如何提问,请随时提及答案。

错误消息准确无误。协议的要求是:

func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T
有一个函数需要任何类型的解析器来解析任何 可解析对象

为什么不使用Swift的内置可解码协议?它的设计目的是为广泛的数据类别解决这个问题。以下是它的假设:您可能想要解析的每种数据都属于以下类别之一:

表示单个基元值的数据,如数字或字符串 表示对象集合的数据,其中每个对象都属于这三个类别之一 与2类似,但每个对象也有一个键 请注意,这些类别是递归的,因此这很自然地表示类似于JSON的内容,其中可以有一个包含字符串的对象的数组

Swift中的解码器(如JSONDecoder)可以获取数据并尝试将其解释为这三个类别之一,特别是SingleValueDecodingContainer、UnkeyedDecodingContainer或KeyedDecodingContainer

然后,一个可解码类知道如何从这三个类别中选择一个并实例化自己*

因此,只要您认为可以为使用一个或多个类别的所有可解析对象编写初始值设定项,您的对象就可以简单地符合内置的可解码协议

如果您想要一个定制的解析器,比如ProtoBufParser,那么您所要做的就是告诉它如何通过实现协议来生成一个通用容器类型

这就是允许您将任何类型的解析器与任何类型的可解析对象混合和匹配的方式


*从技术上讲,可解码对象使用解码器本身来实例化自身。例如,这允许您在构造器中尝试多种可选解码策略,直到某种方法起作用。

Hmmm。。。你是对的。但是我如何才能从外部隐藏原始的通用函数呢?我知道我可以定义不同的协议,但它们都需要以某种方式统一起来。我需要屏蔽总是错误的版本。这种方法类似于旧的OOP继承问题。@MojtabaHosseini那么您需要从根本上重新思考您的设计。如果您的协议说您可以解析不可解码的数据类型,并且您的JSONParser实现了该协议,那么如果您让它编译,编译器将允许您向它传递不可解码的数据类型,谢谢你的关注,麦克斯。我想我无法很好地解释我的问题。我在最初的问题中已经提到了这一点。我需要在不丢失父存根的情况下自定义继承的协议存根,因为有些数据类型不能像消息示例那样进行解码。@MojtabaHosseini为什么不能通过添加扩展使其可解码?在Swift中,说您想要解析不可解码的东西是一种矛盾。“可解码”是您将某事物标记为可解析的方式!
protocol ProtobufParser: Parser {
    func parseData<T: Message>(_ data: Data, to: T.Type) throws -> T
}

extension ProtobufParser {
    func parseData<T: Message>(_ data: Data, to: T.Type) throws -> T { try T.init(serializedData: data) }
}
func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T
func parseData<T: Decodable & DataType>(_ data: Data, to: T.Type) throws -> T
extension JSONParser {
  func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T where T: Decodable {
    try jsonDecoder.decode(T.self, from: data)
  }

  func parseData<T: DataType>(_ data: Data, to: T.Type) throws -> T {
    throw CannotDecodeError
  }
}