Наследование протокола Swift и связанный тип - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть протокол с ассоциированным типом

protocol IBaseDao {
    associatedtype Entity

    func insert(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
    func insertReplacing(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
    func delete(e: Entity, completion: @escaping (Result<Int, Error>) -> Void)
    func update(e: Entity, completion: @escaping (Result<Entity, Error>) -> Void)
    func load(id: String, completion: @escaping (Result<Entity, Error>) -> Void)
    func loadAll(completion: @escaping (Result<[Entity], Error>) -> Void)
}

Затем я хочу добавить конкретные протоколы для конкретного типа сущности, например, так:

protocol IMoviesDao : IDao where Entity == Movie {

    func load(query: String, completion: @escaping (Result<[Movie], Error>) -> Void)
}

Затем у меня есть реализация BaseDao, как показано ниже:

class UserDefaultsDao<T> : IDao {

    typealias Entity = T
}

Тогда у меня есть реализация конкретного класса Dao:

class MoviesUserDefaultsDao : UserDefaultsDao<Movie>, IMoviesDao {

}

Наконец, я хотел бы использовать:

final class MoviesRepository {

    private let moviesService : IMoviesService
    private let moviesDao : IMoviesDao
}

Но здесь я получаю сообщение об ошибке:

Протокол 'IMoviesDao' можно использовать только в качестве общего ограничения, поскольку он имеет требования к Self или связанные с типами

Можно ли как-то обойти эту проблему?Я считаю, что повторное указание тех же методов в IMoviesDao, что и в IBaseDao, и удаление наследования (расширения) протокола сделают эту работу, но затем мне нужно переписать эти методы для каждого протокола Dao

ОБНОВЛЕНИЕ:

Так что теперь мне нужно продублировать этот метод

protocol IMoviesDao {

    func load(query: String, completion: @escaping (Result<[Movie], Error>) -> Void)

    func insert(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
    func insertReplacing(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
    func delete(e: Movie, completion: @escaping (Result<Int, Error>) -> Void)
    func update(e: Movie, completion: @escaping (Result<Movie, Error>) -> Void)
    func load(id: String, completion: @escaping (Result<Movie, Error>) -> Void)
    func loadAll(completion: @escaping (Result<[Movie], Error>) -> Void)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...