Swift 3中最小的工作IteratorProtocol / Sequence [英] Minimal working IteratorProtocol / Sequence in Swift 3

查看:112
本文介绍了Swift 3中最小的工作IteratorProtocol / Sequence的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆