为什么可以';在Swift Combine中,我不能在.tryMap()之后使用.flatMap()?

为什么可以';在Swift Combine中,我不能在.tryMap()之后使用.flatMap()?,swift,combine,Swift,Combine,我正在学习和尝试一些东西,并结合我自己的申请,并进入了以下情况与这个人为的例子 let sequencePublisher = [70, 5, 17].publisher var cancellables = [AnyCancellable]() sequencePublisher // .spellOut() .flatMap { query -> URLSession.DataTaskPublisher in return URLSession.shar

我正在学习和尝试一些东西,并结合我自己的申请,并进入了以下情况与这个人为的例子

let sequencePublisher = [70, 5, 17].publisher
var cancellables = [AnyCancellable]()

sequencePublisher
//    .spellOut()
    .flatMap { query -> URLSession.DataTaskPublisher in
        return URLSession.shared.dataTaskPublisher(for: URL(string: "http://localhost:3000?q=\(query)")!)
    }
    .compactMap { String(data: $0.data, encoding: .utf8) }
    .sink(receiveCompletion: { completion in
        switch completion {
        case .failure(let error):
            print(error.localizedDescription)
        default: print("finish")
        }
    }) { value in
        print(value)
    }
    .store(in: &cancellables)
我有一个序列发布器,它发出3个整数,我通过
flatMap
传递它,并向本地API发送一个Get请求,该请求只返回它嵌入到字符串中的相同值

这一切都很好,我在sink中得到了所有3个API响应,只要我不取消对
spellOut()
自定义运算符的注释,如果该数字小于6,则该运算符应该失败,其作用如下:

enum ConversionError: LocalizedError {
    case lessThanSix(Int)
    var errorDescription: String? {
        switch self {
        case .lessThanSix(let n):
            return "could not convert number -> \(n)"
        }
    }
}

extension Publisher where Output == Int {
    func spellOut() -> Publishers.TryMap<Self, String> {
        tryMap { n -> String in
            let formatter = NumberFormatter()
            formatter.numberStyle = .spellOut
            guard n > 6, let spelledOut = formatter.string(from: n as NSNumber) else { throw ConversionError.lessThanSix(n) }
            return spelledOut
        }
    }
}
enum ConversionError:LocalizedError{
案件lessThanSix(内部)
var errorDescription:字符串{
切换自身{
案例。lessThanSix(让n):
return“无法转换数字->\(n)”
}
}
}
输出==Int的扩展发布服务器{
func spellOut()->publisher.TryMap{
tryMap{n->输入字符串
let formatter=NumberFormatter()
formatter.numberStyle=.spellOut
guard n>6,让spelledOut=formatter.string(from:n作为NSNumber)else{throw ConversionError.lessThanSix(n)}
返回拼写输出
}
}
}
如果我在flatMap开始工作之前添加另一个
map
操作符,代码甚至不会编译,但是使用tryMap它只会说

调用实例方法“flatMap”时没有精确匹配

有没有办法做到这一点,或者为什么不允许


提前感谢您的回答

这里的问题是,
FlatMap
要求在其关闭中创建的返回发布服务器具有与其上游相同的
故障
类型(除非上游具有
从不
故障)

所以,一个
序列
发布者,比如:

let sequencePublisher = [70, 5, 17].publisher
故障类型为
从不
且所有工作正常

但是
TryMap
,也就是
.spellOut
操作符返回的,有一个故障类型
Error
,因此它失败了,因为
DataTaskPublisher
有一个
urleror
故障类型


一种修复方法是匹配
flatMap
中的错误类型:

sequencePublisher
    .spellOut()
    .flatMap { query in
        URLSession.shared.dataTaskPublisher(for: URL(...))
           .mapError { $0 as Error }
    }
    // etc...

这里的问题是
FlatMap
要求在其闭包中创建的返回发布服务器与其上游发布服务器具有相同的
Failure
类型(除非上游发布服务器具有
Never
Failure)

所以,一个
序列
发布者,比如:

let sequencePublisher = [70, 5, 17].publisher
故障类型为
从不
且所有工作正常

但是
TryMap
,也就是
.spellOut
操作符返回的,有一个故障类型
Error
,因此它失败了,因为
DataTaskPublisher
有一个
urleror
故障类型


一种修复方法是匹配
flatMap
中的错误类型:

sequencePublisher
    .spellOut()
    .flatMap { query in
        URLSession.shared.dataTaskPublisher(for: URL(...))
           .mapError { $0 as Error }
    }
    // etc...