Swift 3中最小的工作IteratorProtocol / Sequence [英] Minimal working IteratorProtocol / Sequence in Swift 3
问题描述
我发现在Swift 3中使用Sequence / IteratorProtocol找到工作文档非常困难。有些教程/文章似乎适用于较旧的Swift。
I've found it remarkably difficult to find "working documentation" for using Sequence / IteratorProtocol in Swift 3. The few tutorials/articles out there seem to be for older Swift.
想象一下名为 DLList
的玩具双向链表类...
Imagine a toy doubly-linked list class called 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
在中为
结构。
I believe the following represents the simplest (?), correct, way to make it that you can, in a word, use DLList
in a for
structure.
public class DLList:Sequence
{
// toy linked list class here
public func makeIterator() -> DLListIterator
{
return DLListIterator(self)
}
}
您似乎只需要添加 makeIterator
电话。
It would seem that all you have to do is add the makeIterator
call.
由于该类是DLList,我们称之为DLListIterator。似乎
Since the class is DLList, we'll call it DLListIterator. It would seem that
1,你必须有一个init,它基本上是有问题的小组类
1, you have to have an "init" which basically takes the group class in question
2,你必须有一个 next
调用,它必须返回一个与你的组类神奇相关的东西。
2, you have to have a next
call, which must return one of the "things" which are magically related to your group class.
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
}
}
这似乎完美无缺。即,你现在可以去
This does seem to work perfectly. ie, you can now go
var d:DLList = DLList()
for n in d
{
print or whatever n
}
您可以使用 e = d.filter({d.item blah})
等等 - 很棒。
you can use e = d.filter( {d.item blah} )
and so on - great.
问题 - 有很多关于关联类型的讨论。在第1部分中,您是否以某种方式明确声明/添加关联类型?即使没有明确要求你会如何明确地执行?这个相关类型的业务到底是什么?
Question - there's a lot of talk about associated types. In part 1, do you somehow explicitly state/add the "associated type"? Even if it's not explicitly required how would you do that explicitly? What the hell is this associated type business?
问题 - 在第二部分我完全不知道它是如何知道Node是与DLList有关的东西。有没有办法让这个显而易见,或者我不理解什么?
Question - in part two I'm completely mystified how it "knows" that Node is the "thing" that relates to DLList. Is there a way to make that explicit, or what am I not understanding?
迅捷此外,整个事情看起来并不是非常迅速。这样做只是为了添加迭代器输出似乎令人难以置信。对于一个真正的类,在Swift3中有一种更快捷的方式吗? (不是像倒计时数字这样的愚蠢的例子。)
Swiftness Moreover, the whole thing seems not very Swifty. It seems incredible to do all that just to add iterator output. In Swift3 is there a snappier way, for a real class? (Not a silly example like "countdown numbers".)
最后的问题我高兴地提到上面现在允许和.filter。事实上,我的例子是完整的 - 我现在可以用DLList做一切iterator-wise,一个人可以在Swift中正常做 - 我可能忘记了一些功能或者??在使DLList成为一个非常好的迭代器时还有更多工作要做吗?
Final question I cheerfully mention that the above now allows for and .filter. In fact, is my example "complete" - can I now do everything "iterator-wise" with DLList, that one can do normally in Swift - have I perhaps "forgotten some features" or ?? Is there more to do in making DLList a really good iterator?
推荐答案
这一切都很适合通过类型推理(真的很强大的东西在斯威夫特)。
It all nicely works via type inference (really strong thing in Swift).
例如 IteratorProtocol
只有一个要求,即 next() - >元素?
方法。如果您只是在XCode中单击 IteratorProtocol
,就可以看到以下内容:
E.g. IteratorProtocol
has only one requirement, that is next() -> Element?
method. Here is what you can see if you just Cmd-click on IteratorProtocol
in XCode:
public protocol IteratorProtocol {
associatedtype Element
public mutating func next() -> Self.Element?
}
因此,如果您声明类型符合 IteratorProtocol
并提供一些 next() - >的实现Foo?
然后Swift立即推断 Foo
必须是元素
。
So if you declare a type to conform to IteratorProtocol
and provide an implementation of some next() -> Foo?
then Swift immediately infers that Foo
must be an Element
.
当然,您可以通过以下方式明确声明:
You can, of course, make an explicit declaration via:
public class DLListIterator: IteratorProtocol {
public typealias Element = Node
public func next() -> Element? {
// ...
}
}
,是的,一旦你实现了(序列
和迭代器
),你可以做其他序列可以做的所有事情。这一切都要归功于默认的协议实现。
And, yes, once you implemented both (Sequence
and Iterator
, that is) you can do everything that other Sequences can do. All this thanks to default protocol implementations.
是否所有这些样板都是为了符合 Sequence
你需要提供 makeIterator()
,反过来必须提供 next()
,是不是Swifty ..我认为这是更多基于意见的东西。有时,您可以实现 Sequence
,而无需实现 IteratorProtocol
(例如,当您实现包装器时)。所以,拆分确实对我有意义。
Whether all this boilerplate that in order to conform to Sequence
you need to provide makeIterator()
, that in turn has to provide a next()
, is Swifty or not.. I think this is something more of opinion-based. Sometimes, you can implement Sequence
without going down to implementing IteratorProtocol
(e.g. when you implement a wrapper). So, the split does make sense to me.
这篇关于Swift 3中最小的工作IteratorProtocol / Sequence的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!