我一直在阅读这个 Swift 包 SwiftUIPager 的源代码,并在第 186 行找到了这个扩展:
extension Pager where ID == Element.ID, Element : Identifiable {
/// Initializes a new Pager.
///
/// - Parameter data: Array of items to populate the content
/// - Parameter content: Factory method to build new pages
public init(page: Binding<Int>, data: [Element], @ViewBuilder content: @escaping (Element) -> PageView) {
self._pageIndex = page
self.data = data
self.id = Element.id
self.content = content
}
}
原始 init(第 144 行(明确要求id
,而这个则没有,因为 Element 的类型是可识别的。
我不明白的代码的一部分是为什么ID == Element.ID
是必要的,它到底意味着什么?删除它会导致编译时错误:Key path value type 'Element.ID' cannot be converted to contextual type 'ID'
斯威夫特的文档只谈到了A == B
,我理解这一点,但A == B.A
应该是什么意思?
Pager
类型定义为泛型类型Element
、ID
和PageView
struct Pager<Element, ID, PageView>: View
对每个都有约束:
where PageView: View, Element: Equatable, ID: Hashable {
该扩展适用于泛型类型ID
Pager
与泛型类型ID
Element
相同的情况,并且Element
符合Identifable
:
extension Pager where ID == Element.ID, Element : Identifiable
为什么Element
应该有一个泛型类型ID
?因为Element
被约束为Identifiable
,它是用关联的类型ID
定义的:
protocol Identifable {
associatedtype ID
...
}
因此,换句话说,仅当Pager
Element
具有符合Identifiable
时,扩展才适用,ID
类型与其自己的ID
查看此代码,它看起来像 Element 是一个数组。 Element.Id 正在查看数组中该特定元素的 ID。因此,它正在检查元素 ID 是否等于 ID。如果你没有 element.id 它就不知道它应该查看数组中的哪个元素。