Generi c параметр 'Result' не может быть выведен с помощью RxSwift - PullRequest
1 голос
/ 24 апреля 2020

Я новичок в Swift, так что, возможно, вопрос немного глупый. Я не знаю, почему я получил ошибку здесь:

htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
            .subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
            .map { //Generic parameter 'Result' could not be inferred
                let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self.parsingType)
                return parsingHelper.parseActionItems(document: $0)
            }

Чтобы устранить ее, мне пришлось добавить

.map { doc -> [MyItem] in
     let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self.parsingType)
     return parsingHelper.parseActionItems(document: doc)
}

Когда я могу опустить params и return тип?

1 Ответ

2 голосов
/ 24 апреля 2020

Чтобы вывод типа работал в замыканиях, обычно требуется либо внешняя область видимости, чтобы знать тип, либо само замыкание должно состоять из одной строки. Это ограничение в системе типов Swift. Так что либо:

htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
    .subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
    .map {
        ParsingTypeFactory.getParsingType(parsingType: self.parsingType).parseActionItems(document: $0)
    }

, либо

let myItems: Observable<[MyItem]> = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
    .subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
    .map {
        let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self.parsingType)
        return parsingHelper.parseActionItems(document: $0)
    }

Другие варианты:

Обратите внимание, что во всех рассмотренных выше случаях вы строго ссылаетесь на себя и, вероятно, вызывает цикл памяти / утечка. Вы можете избежать этого, создав вспомогательную функцию, которая не является частью класса:

// do NOT put this in the class, make it a free function (possibly private to avoid namespace pollution.)
func parser(for parsingType: ParsingType) -> (Document) -> [MyItem] {
    return { document in
        let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: parsingType)
        return parsingHelper.parseActionItems(document: document)
    }
}

И теперь этот код становится:

let myItems = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
    .subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
    .map(parser(for: parsingType))

Если вы не Вам не нравится идея свободной функции, или вам не нравится функция, которая возвращает функцию, вы можете поместить функцию в расширение в ParserType:

extension ParsingType {
    func parser(document: Document) -> [MyItem] {
        let parsingHelper = ParsingTypeFactory.getParsingType(parsingType: self)
        return parsingHelper.parseActionItems(document: document)
    }
}

, и теперь оригинальный код становится:

let myItems = htmlHelper.fetchHtmlObservable(url) // this one is an Observable<String> function
    .subscribeOn(ConcurrentDispatchQueueScheduler.init(qos: .background))
    .map(parsingType.parser(document:))

Это также позволяет избежать ссылки на себя.

...