当自我实现迭代协议时,Swift如何推断序列需求?

当自我实现迭代协议时,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? {

我正在阅读序列文档,在他们使用的一个示例中(见下文),推断了序列的需求。我的问题是如何推断。我理解推理在更简单的情况下是如何工作的,但在这个例子中,我无法理解斯威夫特是如何推理的

我看到Sequence的makeIterator方法有一个默认实现,但我不理解这里返回值是如何推断的

示例

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我不知道你是什么意思,但我已经尽了最大的努力,还是编辑了。请随意建议您自己编辑:)