Как сделать структуру соответствующей протоколу, свойство которого соответствует другому протоколу в swift 4? - PullRequest
0 голосов
/ 12 сентября 2018

Я собирался отразить некоторые данные JSON из веб-службы в быстрой структуре. Поэтому я создал протокол, который соответствует декодируемому протоколу, и планировал создать некоторые структуры для его соответствия. Это протокол, который я создал:

protocol XFNovelApiResponse: Decodable {

   var data: Decodable {get}
   var error: NovelApiError {get}
}

struct NovelApiError: Decodable {

   let msg: String
   let errorCode: String
}

Это было скомпилировано. Но когда я начал писать свою структуру, я получил ошибку. Код структуры здесь:

struct XFNovelGetNovelsApiResponse: XFNovelApiResponse {

    let data: NovelsData

    let error: NovelApiError

    struct NovelsData: Decodable {

    }
}

Ошибка говорит, что тип 'XFNovelGetNovelsApiResponse' не соответствует протоколу 'XFNovelApiResponse' . Я знаю, что свойство data должно быть реализовано неправильно. Как я могу это исправить? Спасибо.

1 Ответ

0 голосов
/ 12 сентября 2018

Вы просите описать тип типа, который может содержать data, а не фактический тип. Это означает, что это должно быть associatedtype:

protocol XFNovelApiResponse: Decodable {
    associatedtype DataType: Decodable
    var data: DataType {get}
    var error: NovelApiError {get}
}

Обратите внимание, что протоколы со связанными типами могут создавать большую сложность, поэтому вам следует тщательно продумать, действительно ли этот протокол необходим или, например, XFNovelApiResponse может, например, быть универсальным. Это зависит от того, какие другие типы реализуют этот протокол.

Например, другая реализация подобного набора структур данных без протоколов будет:

struct XFNovelApiResponse<DataType: Decodable>: Decodable {
    var data: DataType
    var error: NovelApiError
}

struct NovelsData: Decodable {
}

struct NovelApiError: Decodable {

    let msg: String
    let errorCode: String
}

let novels = XFNovelApiResponse(data: NovelsData(),
                                error: NovelApiError(msg: "", errorCode: ""))

Кроме того, вы можете реализовать это с помощью классов и подклассов, которые разрешают наследование. Структуры не наследуются от протоколов, они соответствуют протоколам. Если вы действительно имеете в виду наследование, классы - правильный инструмент. (Но я думаю, что дженерики - лучшее решение здесь.)

...