来自源代码
public protocol RandomAccessCollection<Element> : BidirectionalCollection where Self.Indices : RandomAccessCollection, Self.SubSequence : RandomAccessCollection {
associatedtype Element
我们可以看到RandomAccessCollection
将Element
定义为关联类型。这个重新定义的意义是什么?
并且 Array 符合此 RandomAccessCollection
协议(protocol)。来自数组的源代码
@frozen public struct Array<Element> {
...
}
也会有一个Element
。
这3个元素之间有什么联系吗?
最佳答案
RandomAccessCollection
重新声明Element
来自BidirectionalCollection
没有必要。删除声明不会破坏任何内容或向代码添加任何新功能。
protocol Foo<T> {
associatedtype T
}
protocol Bar<T>: Foo {
associatedtype T
}
编译为完全相同的内容:
protocol Foo<T> {
associatedtype T
}
protocol Bar<T>: Foo {
}
试试 godbolt.org !
我能看到的唯一区别是生成的文档。通过重新定义Element
, RandomAccessCollection.Element
有单独的页面和 BidirectionalCollection.Element
,直接从页面链接到 RandomAccessCollection
和BidirectionalCollection
.
无需重新声明Element
,不太明显 RandomAccessCollection
有一个 Element
关联类型,因为您必须转到“Inherits from ”部分并转到声明 Element
的协议(protocol)看到它确实有Element
作为关联类型。
也就是说,您可以说您可以立即推断出 RandomAccessCollection
有一个 Element
通过查看 Element
关联类型是其声明中的主要关联类型:
protocol RandomAccessCollection<Element>
但是旧版本的 Swift 中不存在主要关联类型,因此作者最初这样做的原因仍然是有道理的。另外,RandomAccessCollection
重新声明的不仅仅是 Element
。还有Index
, SubSequence
等
通过重新声明关联的类型,在阅读文档时一目了然,协议(protocol)需要什么类型。
此外,您还可以在每个关联的类型声明上编写不同的文档文本。
protocol Foo<T> {
/// something describing T...
associatedtype T
}
protocol Bar<T>: Foo {
/// something describing T that is more specific to Bar...
associatedtype T
}
至于Element
在Array<Element>
,这是一个泛型类型参数,实现 RandomAccessCollection
的关联类型要求。 (以及许多其他协议(protocol))。它本身不是关联的类型声明。
关于swift - 为什么要重新定义 Swift RandomAccessCollection 协议(protocol)中的 Element 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77500329/