Swift调用Combine的flatMap时出现Generic parameter 'Output' could not be inferred错误
问题原因
- Swift 仅对单表达式闭包支持自动类型推断,未加
print语句时闭包只有return一行代码,编译器可以自动推导返回的Publisher类型,不会报错。添加print语句后闭包变为多表达式结构,编译器无法自动推导flatMap的泛型参数,需要你手动明确声明返回类型。 - 你手写的返回类型
-> Just本身是错误的:Just是带泛型参数的类型,且你在Just之后链式调用了decode、catch操作符,最终返回的Publisher类型已经不是Just,是经过操作符组合后的复杂复合类型,无法直接用Just声明。 - 原代码还存在订阅未持有、缺少订阅触发的问题:
flatMap返回的Publisher没有赋值给cancellable属性,也没有调用sink/assign触发订阅,就算编译通过也会因为订阅立刻释放,拿不到执行结果。
解决方案
修改flatMap闭包的返回类型声明,调用eraseToAnyPublisher()擦除复杂的Publisher类型,简化类型声明即可。修改后的完整可运行代码如下:
import Foundation import Combine class JustViewObservableObject: ObservableObject { var cancellable: AnyCancellable? struct Student: Decodable { let name: String } let json = """ [{ "name": "李雷" }] """ init() { let publisher = PassthroughSubject<String, Never>() // 明确闭包返回类型为AnyPublisher<输出类型, 错误类型> cancellable = publisher.flatMap { value -> AnyPublisher<[Student], Never> in print("value == \(value)") return Just(value.data(using: .utf8)!) .decode(type: [Student].self, decoder: JSONDecoder()) .catch { _ in Just([Student(name: "无名氏")]) } .eraseToAnyPublisher() // 擦除复合Publisher类型为通用的AnyPublisher } // 添加订阅触发Publisher执行 .sink(receiveValue: { students in print("解析结果:\(students)") }) publisher.send(json) } }
内容的提问来源于stack exchange,提问作者SpaceZhong
相关产品推荐
相关产品推荐

