我发现很难找到在Swift 3中使用Sequence/IteratorProtocol的“工作文档”。那里的一些教程/文章似乎适用于较早的Swift。
想象一下一个名为DLList
的玩具双向链接列表类...
public class Node
{
// whatever "thing" you have a group of, this is that "thing"
}
public class DLList
{
// toy linked list class here
// so this is a group of "node" in this example
}
我相信以下内容代表了最简单的(?)正确方法,即可以一句话在DLList
结构中使用for
。步骤1,使您的DLList符合DLList:Sequence
public class DLList:Sequence
{
// toy linked list class here
public func makeIterator() -> DLListIterator
{
return DLListIterator(self)
}
}
似乎您所需要做的就是添加makeIterator
调用。步骤2,编写您的迭代器,符合
IteratorProtocol
由于该类是DLList,因此我们将其称为DLListIterator。看来1,您必须有一个“init”,该“init”基本上可以使用相关的组
2,您必须有一个
next
调用,该调用必须返回与组类魔术相关的“事物”之一。public class DLListIterator:IteratorProtocol
{
var dll:DLList // you must know the group in question
var pointer:Node? // you must know where you are
init(_ dll:DLList)
{
// so note those two items
self.dll = dll
self.pointer = dll.firstOne
}
public func next() -> Node?
{
// return the next one; careful to return nil at end.
let thisOne = self.pointer
self.pointer = self.pointer?.nextOne
return thisOne
}
}
这似乎确实工作正常。即,您现在可以var d:DLList = DLList()
for n in d
{
print or whatever n
}
您可以使用e = d.filter( {d.item blah} )
等-太好了。问题-关于关联类型的讨论很多。在第1部分中,您是否以某种方式明确声明/添加了“关联类型”?即使没有明确要求,您将如何明确地执行?这个相关类型的业务到底是什么?
问题-在第二部分中,我完全迷惑了它如何“知道” Node是与DLList相关的“事物”。有没有办法使之明确,或者我不明白什么?
迅捷此外,整个事情似乎并不十分迅捷。仅仅添加迭代器输出似乎很难做到。在Swift3中,对于真实的类,有一种更简单的方法吗? (不是一个愚蠢的例子,例如“倒数”。)
最后一个问题我很高兴地提到以上内容现在允许和.filter。实际上,这是我的示例“完成”-我现在可以使用DLList在“迭代器方式”上做所有事情,而在Swift中可以正常执行吗?使DLList成为真正好的迭代器还有更多工作要做吗?
最佳答案
通过类型推断(在Swift中确实很强大),所有这些都可以很好地工作。
例如。 IteratorProtocol
仅具有一个要求,即next() -> Element?
方法。如果您仅单击CCode并单击XCode中的IteratorProtocol
,就会看到以下内容:
public protocol IteratorProtocol {
associatedtype Element
public mutating func next() -> Self.Element?
}
因此,如果您声明一个符合
IteratorProtocol
的类型并提供某种next() -> Foo?
的实现,则Swift会立即推断Foo
必须是Element
。当然,您可以通过以下方式进行明确的声明:
public class DLListIterator: IteratorProtocol {
public typealias Element = Node
public func next() -> Element? {
// ...
}
}
而且,是的,一旦实现了两者(即
Sequence
和Iterator
),您就可以完成其他Sequence可以完成的所有工作。这一切都要归功于默认协议(protocol)的实现。为了符合
Sequence
而需要提供makeIterator()
,而又必须提供next()
的所有样板,是否都是Swifty。有时,您可以执行Sequence
,而不必执行IteratorProtocol
(例如,当实现包装器时)。因此,拆分对我来说确实有意义。关于iterator - Swift 3中的最小工作IteratorProtocol/Sequence,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40350731/