首页 > 解决方案 > for 什么时候调用迭代器方法?

问题描述

这个问题与其他关于使块可迭代的问题相同,但似乎揭示了 mixins 的不同问题(或我对语法的不同误解)。这样做Iterable是为了使数据结构有效地可迭代,也就是说,您可以通过在它前面加上for.

Iterable 用作对象的 API,可以使用 for 构造和相关的迭代构造进行迭代,例如超级运算符。

因此,让我们尝试将其付诸实践:

 my &logger = -> $event  {
    state %store;
    if ( $event ) {
        %store{ DateTime.new( now ) } = $event;
    } else {
        %store;
    }
}

role Forable does Iterable {
    method iterator(&self:) {
        self( Nil );
    }
}

logger( "One" );
logger( "Two" );

&logger does Forable;

.say for &logger;

这根本行不通;say被应用&logger为一个简单的项目。但是,如果我们将最后一句话更改为:

.say for &logger.iterator;

我猜这表明该角色实际上正在工作,并且混入其中。由于 for 的类型&loggerBlock+{Forable},如果 Iterable 没有直接混入,它可能不起作用。事实上,does IterableForable声明中删除不会以任何方式影响它。让我们试试这个:

&logger does (Iterable,Forable);

现在的类型&logger显示为Block+{Iterable,Forable},但仍然没有喜悦。iterator必须直接调用。关于如何解决这个问题的任何想法?

标签: mixinsraku

解决方案


我不认为你可以。基本问题是&fooCallable对象)和foo()(调用Callable对象)是两个非常不同的东西。

对我来说,您正在尝试将 a 添加method到 a class,但您正在使用 a Sub

您需要iterator在 的返回值上混合该方法logger。由于我不太了解您要达到的目标,因此很难回答这个问题。

看着你显然想要达到的结果,我想出了这个:

my %store;
multi sub logger() {
    %store
}
multi sub logger($event) {
    %store{ DateTime.new( now ) } = $event;
}

logger( "One" );
logger( "Two" );

.say for logger;

但这根本不使用roles 。所以这可能不是你想要的。


推荐阅读