[Raku文档中指出,正在对收集结构进行惰性评估。在以下示例中,我很难得出关于结构的惰性的结论:
say 'Iterate to Infinity is : ', (1 ... Inf).WHAT;
say 'gather is : ', gather {
take 0;
my ($last, $this) = 0, 1;
loop {
take $this;
($last, $this) = $this, $last + $this;
}
}.WHAT;
say '------------------------------------';
my @f1 = lazy gather {
take 0;
my ($last, $this) = 0, 1;
loop {
take $this;
($last, $this) = $this, $last + $this;
}
}
say '@f1 : ', @f1.WHAT;
say '@f1 is lazy : ', @f1.is-lazy;
say '------------------------------------';
my @f2 = 1 ... Inf;
say '@f2 : ', @f2.WHAT;
say '@f2 is lazy : ', @f2.is-lazy;
在第一种情况下(如果将“ seq分配给@ f1,如果我们取消了” lazy“定义,则生成的Sequence(使用collect-take)将永远运行(不延迟)。
在第二种情况下(将Seq分配给@ f2)@ f2变得懒惰。
我们为什么在行为上有所区别?尽管我们尝试做同样的事情:以惰性方式将Seq分配给数组
有人可以澄清这个问题吗?
gather
不会告诉世界它是懒惰的:
say .is-lazy
for (gather { take 42 }), # False
(gather { loop { take 42 } }); # False
前缀lazy
将创建一个新的Seq
,它将从其右侧的结构中提取。 Seq
创建的新lazy
告诉世界it(新Seq
)是惰性的:
say .is-lazy
for (lazy gather { take 42 }), # True
(lazy gather { loop { take 42 } }); # True
同时,(1...Inf)
知道它是懒惰的,不需要前缀lazy
就可以告诉世界它是:
say .is-lazy
for (1 ... Inf) # True
因此,在您的@f1 = gather ...
情况下,@f1
被分配了一个序列,该序列表示它不是惰性的。因为变量是@
标记,所以赋值操作会忠实地要求序列交付所获得的一切。而Seq
则尽职尽责。但是它包含一个无限循环,因此分配永远不会完成。
在其他情况下,要分配的序列会声明自己是惰性的。 @
变量以此为线索来标记自己为惰性,并且仅懒惰地向序列询问值。这样他们就可以工作。
因此,总而言之,分配给它的@ sigil'd variable is lazy if a
Seq`表示它是惰性的,反之则渴望。
您没有问这个,但是另一种情况是将Seq
分配或绑定到标量变量或无sigil标识符。
在这种情况下,在变量/标识符上调用.is-lazy
将根据分配/绑定的True
返回False
或Seq
。
但是,不管.is-lazy
返回True
还是False
,它都会懒惰地迭代Seq
。