【发布时间】:2016-10-31 21:18:44
【问题描述】:
我发现很难找到在 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
}
我相信以下是最简单 (?)、正确的方法,总而言之,您可以在 for 结构中使用 DLList。
第一步,让你的 DLList 符合 DLList:Sequence
public class DLList:Sequence
{
// toy linked list class here
public func makeIterator() -> DLListIterator
{
return DLListIterator(self)
}
}
看来您所要做的就是添加makeIterator 调用。
第二步,编写你的迭代器,符合IteratorProtocol
由于该类是 DLList,我们将其称为 DLListIterator。好像
1,你必须有一个“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 成为一个非常好的迭代器还有更多工作要做吗?
【问题讨论】:
-
值得注意的是,如果您不需要单独的迭代器类型,并且迭代的逻辑相对简单,您可以使用
AnyIterator(我不知道这是否符合条件对你来说“更 Swifty”)——例如见 this gist. -
@Hamish - 明白了,我想这是捷径,谢谢。很好地使用
defer。多么完美的要点。