swift - “某些协议”导致类型不符合协议
问题描述
我不明白为什么这不能编译。如果我从类型中删除where
限制,它会这样做。P
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
返回类型不仅仅是 any some Publisher
。但在 SwiftUI 中,View
使用了类似的方法,只是它对类型没有限制View
。
有什么办法可以让这段代码编译吗?
解决方案
它不编译的原因是因为some Publisher
声明了一个不透明的类型,但是协议要求该类型必须是“透明的”。
some Publisher
是“不透明的”,因为调用者无法确切地看到属性实际上是什么类型,并且只能知道它符合Publisher
. P.Output
这与必须是的协议要求直接矛盾Int
。要检查P.Output
是Int
,你必须“看穿”some Publisher
,但你不能。
由于编译器无法检查发布者的Output
,它无法检查您的类型是否真的符合协议。因此它选择“安全路线”的结论是你的类型不符合协议。
我认为你应该使用AnyPublisher
类型橡皮擦:
var publisher: AnyPublisher<Int, Never> {
Just(1).eraseToAnyPublisher()
}
SwiftUI 的View
协议没有这个问题,因为它不需要Body
“透视”。它只要求 thatBody
是 , 的构造View
器some View
,根据定义,它是。
推荐阅读
- c++ - 为什么会跳过 Switch 语句?
- c++ - 如何有条件地编写依赖于 C++ 中 lambda 的返回类型的代码?
- r - 使用 purrr 地图在日期上嵌套循环
- html - 进入 Flexbox
- python - 在 luigi 中使用 task_namespace 会产生错误
- javascript - 在鼠标悬停时更改 img
- reactjs - TypeError:this.state 在 reactjs 中不可迭代
- webhooks - 如何使用/显示 rundeck 的 webhook 有效载荷?
- javascript - 如何表示来自 emscripten/webassembly 调用的 void* 返回
- flutter - 如何实现`where`过滤flutter列表中的数据?