swift - "some Protocol"导致类型不符合协议(protocol)

标签 swift combine

我不明白为什么这不能编译。如果我从 P 类型中删除 where 限制,它就会起作用。

import Combine

protocol Foo {
    associatedtype P: Publisher where P.Output == Int
    var publisher: P { get }
}

struct Bar: Foo {
    var publisher: some Publisher {
        Just(1)
    }
}

错误表明类型“Bar”不符合协议(protocol)“Foo”。我猜这是因为 publisher 返回类型不仅仅是任何 some Publisher。但在 SwiftUI 中,View 使用类似的方法,只是它对 View 类型没有限制。

有什么办法可以让这个代码编译吗?

最佳答案

之所以无法编译是因为some Publisher声明了一个不透明的类型,但是协议(protocol)要求该类型必须是“透明的”。

some Publisher 是“不透明的”,因为调用者无法准确看到该属性实际上是什么类型,只能知道它符合 Publisher。这与 P.Output 必须为 Int 的协议(protocol)要求直接矛盾。 要检查 P.Output 是否为 Int,您必须“看透”某个 Publisher,但您可以' t。

由于编译器无法检查发布者的输出,因此它无法检查您的类型是否真正符合协议(protocol)。因此,它选择“安全路线”,得出结论:您的类型不符合协议(protocol)。

我认为您应该使用 AnyPublisher 类型橡皮擦:

var publisher: AnyPublisher<Int, Never> {
    Just(1).eraseToAnyPublisher()
}

SwiftUI 的 View 协议(protocol)不存在这个问题,因为它不要求 Body 是“透明”的。它只要求 BodyView 的一致者,根据定义,some View 就是这样的。

关于swift - "some Protocol"导致类型不符合协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63821754/

相关文章:

ios - 画一条改变方向的线

ios - 观察绑定(bind)或状态变量

Swift结合从func返回发布者

swift - 如何检查URLSession.dataTaskPublisher的当前进度?

ios - iPhone 5、6、6 plus 的 UIlabel 字体大小问题

swift - 在 ARKit 的 SCNPlane 上使用 GPUImage 对视频进行颜色键控

swift - 如何使用 rgba16Float MTLPixelFormat 显示 MTKView

ios - 升级到 Swift 1.2 后的错误

binding - 如何在 View 中翻译绑定(bind)?

ios - SwiftUI 结合 URLSession JSON 网络调用