无法使用 RxSwift 推断通用参数“结果”

Kin*_*uoc 1 closures swift rx-swift

我是 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)
            }
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我必须添加

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

什么时候可以省略 theparamsreturntype?

Dan*_* T. 5

为了使类型推断在闭包中起作用,通常需要外部作用域来了解类型,或者闭包本身需要是一行。这是 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)
    }
Run Code Online (Sandbox Code Playgroud)

或者

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)
    }
Run Code Online (Sandbox Code Playgroud)

其他选项:

请注意,在到目前为止讨论的所有情况下,您都持有对 self 的强引用,并可能导致内存循环/泄漏。您可以通过创建一个不属于该类的辅助函数来避免这种情况:

// 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在有问题的代码变成:

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

如果你不喜欢自由函数的想法,或者你不喜欢返回函数的函数,你可以将该函数放在 ParserType 的扩展中:

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

现在原来的代码变成了:

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

这也避免了保留对 self 的引用。