swift 如何对合并合并运算符的输出使用eraseToAnyPublisher

rdlzhqv9  于 2022-11-21  发布在  Swift
关注(0)|答案(1)|浏览(134)

给定以下代码:

let a = PassthroughSubject<Int, Never>()
let b = PassthroughSubject<Int, Never>()
        
let result = a.merge(with:b).eraseToAnyPublisher()

我本以为result的类型应该是AnyPublisher<Int, Never>,但看起来Xcode将其视为(空格格式为mine):

AnyPublisher<
    Publishers.MergeMany<
        PassthroughSubject<Int, Never>
    >.Output,
    Publishers.MergeMany<
        PassthroughSubject<Int, Never>
    >.Failure
> (aka 'AnyPublisher<Int, Never>')

这和我所期望的并不一样。我猜有一些实现被隐藏了起来,但这并不是我所希望的。很明显,考虑到“aka”部分,Xcode知道它等同于“AnyPublisher〈Int,Never〉”,但为什么它没有完全删除类型呢?
我甚至试着在链的前面删除打字,就像这样:

let a = PassthroughSubject<Int, Never>().eraseToAnyPublisher()
let b = PassthroughSubject<Int, Never>().eraseToAnyPublisher()
        
let result = a.merge(with:b).eraseToAnyPublisher()

这只是稍微好一点,因为Xcode认为result具有类型:

AnyPublisher<
    Publishers.MergeMany<
        AnyPublisher<Int, Never>
    >.Output,
    Publishers.MergeMany<
        AnyPublisher<Int, Never>
    >.Failure
> (aka 'AnyPublisher<Int, Never>')
a1o7rhls

a1o7rhls1#

这是因为eraseToAnyPublisher声明为:

func eraseToAnyPublisher() -> AnyPublisher<Self.Output, Self.Failure>

在您的例子中,SelfPublishers.MergeMany<PassthroughSubject<Int, Never>>>类型,因为merge返回的是Publishers.MergeMany<PassthroughSubject<Int, Never>>>类型。在简单的替换之后,将Self替换为merge返回的类型,eraseToAnyPublisher的返回类型变为:

AnyPublisher<
    Publishers.MergeMany<PassthroughSubject<Int, Never>>.Output,
    Publishers.MergeMany<PassthroughSubject<Int, Never>>.Failure
>

当然,如果您遵循所有类型别名,这与AnyPublisher<Int, Never>是同一类型。
Xcode * 可能 * 被设计成只显示“aka”类型,即在所有类型别名都被解析之后的类型,但这与类型别名的全部意义背道而驰,即类型 * 应该被另一个名称 * 调用。如果我有:

typealias Money = Decimal
func deposit(amount: Money) { ... }

我当然不希望这个函数在Xcode only 中显示为deposit(amount: Decimal)
边注:还可以强制转换为存在类型as an alternative to eraseToAnyPublisher

a.merge(with:b) as any Publisher<Int, Never>

在上面调用eraseToAnyPublisher实际上会给予你一个“短”类型名,但真的没有意义:)

相关问题