角色相对简单。它为迭代器方法提供了一个存根,该方法实际上是由诸如 for 之类的语句使用的。 for 会在它前面的变量上调用 .iterator,然后为每个项目运行一次块。其他方法(如数组赋值)将使 Iterable 类以相同的方式运行。

    在这个示例中,它是 Iterable 中示例的扩展,显示了如何调用 .iterator,只是在将创建的对象分配给变量 @long-chain 时调用此方法;这个变量是一个数组,我们在最后一个例子中对它进行操作。

    (可能有点容易混淆)Iterator 角色比 Iterable 更复杂一点。首先,它提供了一个常量 IterationEnd,但它提供了一系列方法,如 ,它允许在几个上下文中进行更精细的迭代操作:添加或删除项目,或跳过它们以访问其他项目。实际上,该角色为所有其他方法提供了一个默认实现,因此唯一需要定义的方法就是 pull-one,其中只提供了一个 stub。虽然 Iterable 提供了高级变量循环,Iterator 提供了在循环的每次迭代中调用的低级函数。让我们用这个角色扩展前面的例子。

    我们声明一个 DNA 类,它扮演两个角色,IteratorIterable;该类将包含一个字符串,该字符串将被约束为长度为3的倍数且仅由 ACGT 组成。我们先来看看 pull-one 方法。每次发生新的迭代时都会调用这个,因此它必须保持最后一个的状态。 $.index 属性将在调用中保持该状态; 将检查链的末尾是否已到达,并将返回角色提供的 IterationEnd 常量。实际上,实现这种低级接口简化了 Iterable 接口的实现。现在迭代器将成为对象本身,因为我们可以在其上调用 pull-one 来依次访问每个成员;因此,.iterator 将回归自我;这是可能的,因为对象将同时是 IterableIterator

    这并非总是如此,并且在大多数情况下 .iterator 将必须构建要返回的迭代器类型,例如我们在前面的示例中所做的;但是,此示例显示了构建满足迭代器和可迭代角色的类所需的最少代码。

    *

    使用时会发生隐式迭代。

    生成块正在运行一次,而完成序列的条件,在这种情况下,术语大于300,则不满足。这具有运行循环的副作用,但也创建了输出列表。

    这可以通过使用 gather/take 块来更系统地完成,这是一种不同类型的迭代构造,而不是在 sink 上下文中运行,每次迭代都返回一个项目。这个 教程解释了这种循环的用例;实际上, 不是一个循环结构,而是一个语句前缀,它收集 take 生成的项并从中创建一个列表。

    *

    经典循环,循环变量递增,可以通过 在 Raku 中完成。其他 repeat和 循环也是可能的。

    但是,总的来说,他们是沮丧的。 Raku 是一种功能和并发语言;在 Raku 中编码时,你应该以功能的方式看待循环:逐个处理迭代器产生的项目,即将一个项目提供给一个没有任何辅助效果的块。该功能视图还允许通过hyper或自动线程方法轻松并行化操作。

    如果您对旧的循环感觉更舒服,该语言允许您使用它们。但是,在可能的情况下尝试使用功能和并发迭代构造被认为是更多的p6y。

    注意:由于版本6.d循环可以从最后一个语句的值中生成值列表。

    *