如何在协议中声明通用协议属性要求

Posted

技术标签:

【中文标题】如何在协议中声明通用协议属性要求【英文标题】:How to declare a generic protocol property requirement in a protocol 【发布时间】:2017-07-28 08:42:53 【问题描述】:

挣扎了一段时间,如果您能对此有所了解,那将非常有帮助:

我有一个APIWorkerProtocol,它有一个属性要求,所需的属性是一个协议,即DataParserProtocol

protocol APIWorkerProtocol 
    var apiRequestProvider : APIRequestGeneratorProtocol get
    var dataParser : DataParserProtocolget
    func callAPI(completionHandler: @escaping (APICallResult<Self.ResultType>) -> Void)


protocol DataParserProtocol 
    associatedtype ExpectedRawDataType
    associatedtype ResultType
    func parseFetchedData(fetchedData : ExpectedRawDataType) -> APICallResult<ResultType>

我怎样才能做到这一点?

在当前的实现中,这会导致错误Protocol 'DataParserProtocol' can only be used as a generic constraint because it has Self or associated type requirements

提前致谢

Ankit

【问题讨论】:

【参考方案1】:

如果协议使用Self 或相关的类型要求(同构协议),我们可能会注意将该协议用作具体类型。

因此,您可以在APIWorkerProtocol 中添加一个associatedtype 类型,比如DataParser,而不是使用DataParserProtocol 作为dataParser 属性的具体类型(蓝图在APIWorkerProtocol 中),其中被限制为符合DataParserProtocol的类型。

另外,我不确定在callAPI(...) 的完成处理程序中使用Self.ResultType 作为特化的意图是什么(因为Self 将引用实现APIWorkerProtocol 的类型;一个蓝图没有的协议associatedtypeResultType):你的意思是使用DataParserProtocol类型的ResultType吗?

例如

protocol APIWorkerProtocol 
    associatedtype DataParser: DataParserProtocol
    var dataParser : DataParser  get 
    func callAPI(completionHandler: @escaping (APICallResult<DataParser.ResultType>) -> Void)


protocol DataParserProtocol 
    associatedtype ExpectedRawDataType
    associatedtype ResultType
    func parseFetchedData(fetchedData: ExpectedRawDataType) -> APICallResult<ResultType>

【讨论】:

以上是关于如何在协议中声明通用协议属性要求的主要内容,如果未能解决你的问题,请参考以下文章

swift 3.0 协议笔记

如何在 Swift 中覆盖协议扩展的计算属性

协议中的共享实例属性

swift-如何确保最初在哪个协议或类型中定义了特定属性?

我如何知道如何遵守 Swift 中的特定协议?

协议