我正在创建一个协议来抽象不同的模型(手工制作的、可解码的和节俭生成的),如下所示:
protocol FeedItemModeling {
var text: String? { get }
var url: URL? { get }
}
protocol FeedModeling {
var items: [FeedItemModeling]? { get }
}这将工作得很好,除非节俭模型不使用基本的数组,而是一个符合RandomAccessCollection的TList。由于Array和TList都符合RandomAccessCollection,因此我尝试将协议定义更改为:
尝试A)
var items: RandomAccessCollection<FeedItemModeling>? { get }这给出了错误:“无法专门化非泛型类型‘RandomAccessCollection’”。我认为这是因为associatedtype是一个不成熟的泛型,因为它可以在协议本身内部强制执行约束,但不会在外部公开;这意味着在我们的例子中,RandomAccessCollection的associatedtypes在RandomAccessCollection中解析,但FeedModeling没有办法访问它?
尝试B)
var items: RandomAccessCollection? { get }给出了“协议'RandomAccessCollection‘只能用作泛型约束,因为它有自身或关联的类型要求”,并且无论如何都会失去对FeedItemModeling的约束。
尝试C)
associatedtype C: RandomAccessCollection
var items: C? { get }工作,但我们失去了对FeedItemModeling的约束,所以这是不可接受的。
尝试D)
associatedtype C: RandomAccessCollection
var items: C<FeedItemModeling>? { get }给出“无法专门化非泛型类型‘Self.c’。”我想也是因为上面的原因吧?
尝试E)
associatedtype C<E>: RandomAccessCollection where E: FeedItemModeling
var items: C? { get }给出了“关联的类型不能有泛型参数列表”。我假设这是因为现在约束上有一个约束,它不能用这种方式表达?
尝试F)
typealias C<E> = RandomAccessCollection
var items: C<FeedItemModeling>? { get }给出:“协议'RandomAccessCollection‘只能用作泛型约束,因为它有自身或关联的类型要求”。同样的原因?
尝试G)
associatedtype FeedItemModelingList = RandomAccessCollection where RandomAccessCollection.Element: FeedItemModeling
var items: FeedItemModelingList? { get }给出了“关联类型‘元素’只能与具体类型或泛型参数一起使用”。我不明白这个,请告诉我为什么?
尝试H)
protocol FeedItemModelingList: RandomAccessCollection {}
...
var items: FeedItemModelingList? { get }给出:“协议'FeedItemModelingList‘只能用作泛型约束,因为它有自身或关联的类型要求”。
尝试I)
protocol FeedItemModelingList: RandomAccessCollection where Element == FeedItemModeling {}
...
associatedtype L = FeedItemModelingList
var items: L? { get }看起来(到目前为止)还不错,但实际上很难看。
还有更好的主意吗?
发布于 2020-10-10 11:42:19
我想你想要的是
protocol FeedItemModeling {
var text: String? { get }
var url: URL? { get }
}
protocol FeedModeling {
associatedtype TList: RandomAccessCollection where TList.Element == FeedItemModeling
var items: TList? { get }
}至于你的问题:
我认为这是因为关联类型是一个半生不熟的泛型
我认为在现代Swift中,关联类型与泛型非常接近,尽管两者都有些不完整,特别是在现有类型方面,尽管它每年都在变得更好。一条经验法则是许多Swift通用/PAT问题都是用where解决的。
给出了“不能专门化非泛型类型‘self.c’”。我想也是因为上面的原因吧?
IMO这个错误相当糟糕,但它基本上是关于<>的语法问题,它只允许泛型类型,而不允许协议。“专门化”在Swift社区中是一个有点过载的术语,可以表示从类型约束到为已知类型参数值发出机器代码的任何东西。
给出了“关联类型不能有泛型参数列表”。我假设这是因为现在约束上有一个约束,它不能用这种方式表达?
您可以表达对约束的约束,但是没有类似于rust的<F=A>语法yet。目前,您需要where
只能用作泛型约束,因为它具有自身或关联的类型要求。
这就是臭名昭著的"PAT“或”广义存在“问题(参见泛型宣言)。每个人都很恼火,希望有一天我们会支持它。
“关联类型'Element‘只能与具体类型或泛型参数一起使用”。我不明白这个,请告诉我为什么?
RandomAccessCollection只是一种协议,你碰巧在附近使用过,但斯威夫特不知道其中的联系。所以当你这么说的时候
associatedtype FeedItemModelingList = RandomAccessCollection where RandomAccessCollection.Element: FeedItemModeling有点像你做的那样
func foo() where Collection.Element == String在这种情况下,Collection.Element是“封闭的”,没有办法对它进行专门化或给它一个约束。相反,你需要约束一些开放的东西,比如你声明的关联类型。
https://stackoverflow.com/questions/63251024
复制相似问题