Фон:
Я создаю приложение со служебным слоем, который должен возвращать модели, которые похожи (например, у всех есть свойство text: String
, определенное в протоколе TextModel
).Служба содержит репозиторий, который находит и возвращает модели конкретного типа, соответствующие TextModel
.Хранилище должно хранить конкретную информацию о типах для внутренних работ.Я хочу оставить сервис свободным от конкретного типа модели, поэтому мне не нужно повторять его для каждого типа модели.Компилятор не позволяет мне сделать это ...
Проблема:
Следующий код, который я упростил на игровой площадке, не скомпилируется:
enum Result<T> {
case success(T)
case error
}
// Model Layer
protocol TextModel {
var text: String { get }
}
struct Person: TextModel {
let text: String
}
// Service Layer
class TextModelService {
let repository: TextModelRepositoryType
init(repository: TextModelRepositoryType) {
self.repository = repository
}
func find(completion: @escaping (Result<TextModel>) -> ()) {
repository.find(completion: completion)
}
}
// Repository Layer
protocol TextModelRepositoryType {
func find(completion: @escaping (Result<TextModel>) -> ())
}
protocol PersonRepositoryType {
func findPerson(completion: @escaping (Result<Person>) -> ())
}
class PersonRepository: PersonRepositoryType, TextModelRepositoryType {
func find(completion: @escaping (Result<TextModel>) -> ()) {
// ERROR HERE: "Cannot convert value of type '(Result<TextModel>) -> ()' to expected argument type '(Result<Person>) -> ()'"
findPerson(completion: completion)
}
func findPerson(completion: @escaping (Result<Person>) -> ()) {
let person = Person(text: "Adam")
completion(.success(person))
}
}
let repository = PersonRepository()
let service = TextModelService(repository: repository)
service.find { result in
// result should be a Result<Person>
}
Iне понимаю, почему компилятор заявляет, что 'Cannot convert value of type '(Result<TextModel>) -> ()' to expected argument type '(Result<Person>) -> ()'
, когда Person
определенно соответствует TextModel
...
Интересно также то, что когда я удаляю тип Result
и просто передаю развернутыйвведите завершение (например, (TextModel?) -> ()
), компилятор не имеет префиксов.
Я столкнулся с ограничением в компиляторе Swift?Или я что-то упустил?