当自我实现迭代协议时,Swift如何推断序列需求?
我正在阅读序列文档,在他们使用的一个示例中(见下文),推断了序列的需求。我的问题是如何推断。我理解推理在更简单的情况下是如何工作的,但在这个例子中,我无法理解斯威夫特是如何推理的 我看到Sequence的makeIterator方法有一个默认实现,但我不理解这里返回值是如何推断的 示例当自我实现迭代协议时,Swift如何推断序列需求?,swift,types,protocols,sequence,type-inference,Swift,Types,Protocols,Sequence,Type Inference,我正在阅读序列文档,在他们使用的一个示例中(见下文),推断了序列的需求。我的问题是如何推断。我理解推理在更简单的情况下是如何工作的,但在这个例子中,我无法理解斯威夫特是如何推理的 我看到Sequence的makeIterator方法有一个默认实现,但我不理解这里返回值是如何推断的 示例 struct Countdown: Sequence, IteratorProtocol { var count: Int mutating func next() -> Int? {
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
IteratorProtocol {
func next() -> Self.Element?
associatedtype Iterator
associatedtype Element
}
上述类型的参考
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
IteratorProtocol {
func next() -> Self.Element?
associatedtype Iterator
associatedtype Element
}
让我们从
IteratorProtocol.next的实现开始。编译器将看到以下实现:
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
并注意到它返回一个Int?
。好的,应该返回一个Self.Element?
,因此它推断IteratorProtocol.Element==Int
。现在condown
满足IteratorProtocol
请注意,Sequence
和IteratorProtocol
共享关联的类型元素
。一旦Swift找到了iteratorProtocol.Element
的见证,就好像您在Countdown
中声明了一个新的类型别名Element
,恰好Sequence
要求存在Countdown.Element
然后,编译器推断出迭代器==Self
。这使得makeIterator
的默认实现可用。然而,编译器如何推断这一点是一个相当神秘的问题,因为只有这些信息,通常无法推断类型,这可以通过创建自己的序列和迭代器协议来说明
protocol MyIterator {
associatedtype Element
mutating func next() -> Element?
}
protocol MySequence {
associatedtype Element where Element == Iterator.Element
associatedtype Iterator : MyIterator
func makeIterator() -> Iterator
}
extension MySequence where Self == Self.Iterator {
func makeIterator() -> Iterator {
return self
}
}
struct Countdown: MySequence, MyIterator { // doesn't compile
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
在研究了之后,我怀疑可能有一些编译器的神奇之处,尤其是在这里:
// Provides a default associated type witness for Iterator when the
// Self type is both a Sequence and an Iterator.
extension Sequence where Self: IteratorProtocol {
// @_implements(Sequence, Iterator)
public typealias _Default_Iterator = Self
}
这似乎为Iterator
设置了一个“首选”类型,将其推断为。它似乎在说“当迭代器
无法推断为任何东西时,请尝试Self
”。我在其他任何地方都找不到\u Default\u Iterator
,这就是为什么我认为它是编译器的魔力。这样做的全部目的是让您只需遵守迭代协议
并实现下一步
,就可以遵守序列
既然Iterator==Self
,我们也满足了元素
的约束:
associatedtype Element where Self.Element == Self.Iterator.Element
因此,我们已经证明,倒计时
符合顺序
您在顺序
@Sweeper的声明中似乎犯了一个复制粘贴错误,谢谢我刚刚编辑了我可能已经找到了答案。若我们实现Sequence,我们会将:typealias迭代器设置为Self,因为倒计时是一个迭代器,Swift可以推断Self是它自己的迭代器。尽管如此,关于编译器的神奇之处,您还是有一个很好的观点。正如您所指出的,也许您可以重新表述您的答案,以强调编译器推断它的要点,因为它知道self是一个迭代器。我把它标为correct@3366784我不知道你是什么意思,但我已经尽了最大的努力,还是编辑了。请随意建议您自己编辑:)