Быстрое наследование ассоциированного типа - PullRequest
0 голосов
/ 07 мая 2020

Я хочу написать два протокола, один общий c и еще один специальный c для обработки некоторых сетевых запросов.

Все работает нормально для более общего протокола c DORequest, но Я не могу заставить DOPagedRequest работать. Проблема вызвана associatedtype Response, что я хочу сделать больше c в 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.

Ответы [ 2 ]

1 голос
/ 07 мая 2020

В вашем коде есть пара вещей, которые не имеют для меня особого смысла.

Главное, чего я не понимаю, - это характер ответа:

Ответ в DORequest равно: associatedtype Response: DOResponse

Ответ в DOPagedRequest равен where Response: DOPagedResponse.

Таким образом, когда вы объявляете public struct List: DOPagedRequest, компилятор не сможет определить, для какого типа соответствует ли Response.

это Response типа DOResponse или типа DOPagedResponse?

Я бы посоветовал вам сделать что-то, чтобы объединить 2 протокола, а именно: DOResponse и DOPagedResponse под одним зонтом, примерно так:

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 }
}
1 голос
/ 07 мая 2020

Вы забыли унаследовать от DOResponse.

public protocol DOPagedResponse: DOResponse {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...