【问题标题】:"some Protocol" causes type to not conform to protocol“某些协议”导致类型不符合协议
【发布时间】:2020-09-10 01:56:16
【问题描述】:

我不明白为什么这不能编译。如果我从 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)
    }
}

错误提示Type 'Bar' does not conform to protocol 'Foo'。我想这是因为publisher 返回类型不只是任何some Publisher。但是在 SwiftUI 中,View 使用了类似的方法,只是它对 View 类型没有限制。

有什么方法可以编译这段代码吗?

【问题讨论】:

    标签: swift combine


    【解决方案1】:

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

    some Publisher 是“不透明的”,因为调用者无法确切地看到属性实际上是什么类型,并且只能知道它符合Publisher。这直接与P.Output 必须是Int 的协议要求相矛盾。 要检查P.OutputInt,你必须“看穿”some Publisher,但你不能。

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

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

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

    SwiftUI 的View 协议没有这个问题,因为它不需要Body 是“透视”的。它只要求BodyView 的一个conformer,而some View,顾名思义就是。

    【讨论】:

    • 非常明确的答案。我试图避免使用AnyPublisher,但我现在明白为什么不能这样做了。谢谢!
    • 是的,我不知道在这些情况下尝试使用some Publisher 的坏习惯来自哪里。在 SwiftUI 之外,我想不出使用 some 的理由。
    猜你喜欢
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多