Закрытия из нескольких операторов не участвуют в выводе типа , поэтому, сделав закрытие для flatMap многооператорным, вы каким-то образом заставляете его неправильно выводить параметры типа scan
. Вы можете указать нужные типы, написав их в закрытии:
.flatMap { storyIDs -> AnyPublisher<Story, API.Error> in
print("StoryIDs are \(storyIDs)")
return self.mergedStories(ids: storyIDs)
}
Если вы просто хотите напечатать полученные значения, вы также можете вызвать .print()
.
Обновление:
Я немного поиграл с этим и обнаружил, что если вы поместите все до scan
в константу let
и вызовете scan
для этой константы, ошибка переместится куда-нибудь иначе:
let pub = URLSession.shared
.dataTaskPublisher(for: EndPoint.stories.url)
.map(\.data)
.decode(type: [Int].self, decoder: decoder) //<--- Error fires here now!
.mapError { error -> API.Error in
switch error {
case is URLError:
return Error.addressUnreachable(EndPoint.stories.url)
default:
return Error.invalidResponse
}
}
.filter { !$0.isEmpty }
.flatMap { storyIDs in
print("StoryIDs are \(storyIDs)")
return self.mergedStories(ids: storyIDs)
}
return pub.scan([]) { stories, story -> [Story] in
stories + [story]
}
.map { $0.sorted() }
.eraseToAnyPublisher()
Для метода экземпляра 'decode (type: decoder :)' требуются типы 'URLSession.DataTaskPublisher.Output' (aka '(data: Data, response: URLResponse)') и «JSONDecoder.Input» (он же «Данные») должен быть эквивалентен
. На этот раз это привело к неверному выводу аргументов типа decode
. Первоначальная ошибка в scan
исчезла, потому что теперь компилятор знает, что pub
имеет определенный тип, хотя он (неправильно) нашел ошибку где-то еще, прежде чем смог определить тип pub
.
Следуя этой схеме, я сделал еще одну временную let
константу:
let pub1 = URLSession.shared
.dataTaskPublisher(for: EndPoint.stories.url)
.map(\.data)
let pub2 = pub1
.decode(type: [Int].self, decoder: decoder)
.mapError { error -> API.Error in
switch error {
case is URLError:
return Error.addressUnreachable(EndPoint.stories.url)
default:
return Error.invalidResponse
}
}
.filter { !$0.isEmpty }
.flatMap { storyIDs in
print("StoryIDs are \(storyIDs)")
return self.mergedStories(ids: storyIDs)
}
return pub2.scan([]) { stories, story -> [Story] in
stories + [story]
}
.map { $0.sorted() }
.eraseToAnyPublisher()
Наконец, компилятор показывает полезное сообщение на storyIDs in
, которое приводит к использованию решения в начале ответа:
Невозможно определить тип возврата сложного замыкания; добавить явный тип для устранения неоднозначности
Он даже говорит нам, какой тип мы должны вставить!