【问题标题】:Swift associatedtype inheritanceSwift 关联类型继承
【发布时间】:2020-05-07 10:05:24
【问题描述】:

我想编写两种协议,一种是通用的,另一种是专门用于处理一些网络请求的。

对于更通用的DORequest 协议,一切正常,但我无法让DOPagedRequest 工作。问题是由associatedtype Response 引起的,我想在DOPagedRequest 中更具体。

这是我的协议:

public protocol DORequest {
    associatedtype Response: DOResponse
    var method: String { get }
    var path: String { get }
}

public protocol DOResponse: Codable { }

public protocol DOPagedRequest: DORequest where Response: DOPagedResponse {
    var page: Int? { get }
    var perPage: Int? { get }
}

public protocol DOPagedResponse: Codable {
    var links: ResponseLinks { get }
}

public struct ResponseLinks: Codable {

    public struct Pages: Codable {
        var next: String?
    }

    public var pages: Pages?
}

以及它们的具体实现示例:

// Implementation of DORequest with no errors
public struct Get: DORequest {

    public struct Response: DOResponse {
        public let account: String
    }

    public let method = "GET"
    public let path = "account"

    public init() { }
}

// Implementation of DOPagedRequest with errors:
//  Type 'List' does not conform to protocol 'DORequest'
//  Type 'List' does not conform to protocol 'DOPagedRequest'
public struct List: DOPagedRequest {

    public var tag: String?
    public var page: Int?
    public var perPage: Int?

    public struct Response: DOPagedResponse {
        public var links: ResponseLinks

        public let droplets: [String]
    }

    public let method = "GET"
    public let path = "droplets"

    public init(tag: String? = nil, page: Int = 0, perPage: Int = 200) {
        self.tag = tag
        self.page = page
        self.perPage = perPage
    }
}

我可能遗漏了一些关于 Swift 的关联类型的信息。

【问题讨论】:

  • 什么是DO?它看起来像一个 Objective-C 前缀。
  • DO 代表 Digital Ocean,我正在编写 API 包装器????
  • 但是在 Swift 中,你可以使用模块。你不需要前缀。

标签: swift swift-protocols associated-types


【解决方案1】:

你忘了继承DOResponse

public protocol DOPagedResponse: DOResponse {

【讨论】:

    【解决方案2】:

    您的代码中有几处对我来说没有多大意义。

    我不明白的重点是响应的性质:

    DORequest 中的回复是:associatedtype Response: DOResponse

    DOPagedRequest 中的响应是 where Response: DOPagedResponse

    因此,当您声明 public struct List: DOPagedRequest 时,编译器将无法确定 Response 符合哪个类型。

    它是Response 类型的DOResponse 还是DOPagedResponse 类型?

    我建议你做一些事情来统一这两个协议,即:DOResponseDOPagedResponse 在同一个保护伞下,如下所示:

    public protocol GeneralResponse {}
    
    public protocol DOResponse: Codable, GeneralResponse { }
    public protocol DOPagedResponse: Codable, GeneralResponse {
       var links: ResponseLinks { get }
    }
    
    public protocol DORequest {
      associatedtype Response: GeneralResponse
      var method: String { get }
       var path: String { get }
    }
    
    public protocol DOPagedRequest {
       var page: Int? { get }
       var perPage: Int? { get }
    }
    

    【讨论】:

    • 正如@Jessy 所指出的,我忘记了DOPagedResponse 继承自DOResponse,这基本上也是你所指出的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多