“some Protocol” causes type to not conform to protocol

主宰稳场 提交于 2021-02-10 17:50:22

问题


I don't understand why this doesn't compile. It does if I remove the where restriction from the P type.

import Combine

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

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

The error says that Type 'Bar' does not conform to protocol 'Foo'. I guess it's because publisher return type is not just any some Publisher. But in SwiftUI, the View uses a similar approach, just that it doesn't have restrictions over the View type.

Is there any way I can make this code to compile?


回答1:


The reason why it doesn't compile is because some Publisher declares an opaque type, but the protocol requires that the type must be "see-through".

some Publisher is "opaque" in the sense that callers cannot see exactly what type the property actually is, and can only know that it conforms to Publisher. This directly contradicts with the protocol requirement that P.Output has to be Int. To check P.Output is Int, you have to "see through" some Publisher, but you can't.

Since the compiler can't check the publisher's Output, it can't check whether your type really conforms to the protocol or not. Therefore it chooses the "safe route" concludes that your type does not conform to the protocol.

I think you should use the AnyPublisher type eraser:

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

SwiftUI's View protocol does not have this problem because it does not require Body to be "see-through". It just requires that Body is a conformer of View, which some View, by definition, is.



来源:https://stackoverflow.com/questions/63821754/some-protocol-causes-type-to-not-conform-to-protocol

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!