什么时候调用迭代器方法?

jjm*_*elo 4 mixins perl6

这个问题与其他关于使块可迭代的问题在同一个问题,但似乎揭示了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;
Run Code Online (Sandbox Code Playgroud)

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

.say for &logger.iterator;
Run Code Online (Sandbox Code Playgroud)

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

&logger does (Iterable,Forable);
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*sen 5

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

感觉到你在尝试添加methoda 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;
Run Code Online (Sandbox Code Playgroud)

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

  • `Callable`是一个角色.`Sub`,`Routine`,`Block`,`Code`是类.`Callable`角色用于*标记*某些东西可调用(并在某些实用方法中混合).你不能将`Callable`角色放入一个类中,并且可以执行某些操作. (2认同)

rai*_*iph 2

什么时候for调用迭代器方法?

据我了解,如果迭代功能的(单个Scalar)参数是一个容器,那么它使用容器中的值并且不会调用.iterator. 否则,它会调用.iterator它,如果它是表达式或例程调用,则首先对其进行评估。


&logger does Forable;
.say for &logger;
Run Code Online (Sandbox Code Playgroud)

这根本行不通;say被应用为&logger一个简单的项目。

the&是一个名词标记(sigil),标记 aCallable本质上是一个单一的事物,一个单一的代码块。

更具体地说,&logger绑定到一个Scalar类型为 的容器,与您编写的(带有印记)Callable完全相同:$logger$my Callable $logger

say .WHAT, .VAR, .VAR.WHAT, .VAR.of
for my &logger, my Callable $logger
Run Code Online (Sandbox Code Playgroud)

显示:

(Callable)Callable(Scalar)(Callable)
(Callable)Callable(Scalar)(Callable)
Run Code Online (Sandbox Code Playgroud)

由于 的类型&loggerBlock+{Forable}

这实际上是绑定到 的容器中包含的Callable的类型。Scalar&logger

不是容器本身的类型&logger,它是 a Scalar,如上所示。

当以变量的形式给出单个参数时,迭代功能例如for查看变量,而不是变量中包含的值,以查看它是否为Iterable. AScalar不是Iterable

关于如何解决这个问题有什么想法吗?

一种方法请参阅 lizmat 的答案。