Swift关联类型继承

问题描述 投票:0回答:2

我想写两个协议,一个是通用的,一个是比较特殊的,来处理一些网络请求。

通用的协议一切正常 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的associatetype有所遗漏.

swift swift-protocols associated-types
2个回答
1
投票

你忘了继承 DOResponse.

public protocol DOPagedResponse: DOResponse {

1
投票

在你的代码中,有几个地方我觉得不太合理。

我不明白的主要一点是Response的性质。

响应的性质: DORequest 是。associatedtype Response: DOResponse

回应是: DOPagedRequestwhere 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 }
}
© www.soinside.com 2019 - 2024. All rights reserved.