【发布时间】:2021-01-15 04:24:40
【问题描述】:
当我们使用超出数组边界的索引对数组进行切片时,我们会得到未定义 (Any) 的结果
当我们将相同的切片索引作为惰性列表传递时,我们会得到数组/列表的现有值(仅此而已):
my @a = ^5;
say @a[^10]; # (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
say @a[lazy ^10]; # (0 1 2 3 4)
显然切片索引的惰性会影响结果。
试图理解事物的本质,作为概念证明,我编写了我的切片机制的简单版本:
my @a = ^5;
my @s1 = ^10;
my @s2 = lazy ^10;
sub postcircumfix:<-[ ]-> (@container, @index) {
my $iter = @index.iterator;
gather {
loop {
my $item := $iter.pull-one;
if $item =:= IterationEnd {
last;
}
with @container[$item] {
take @container[$item]
} else {
@index.is-lazy ?? { last } !! take @container[$item];
}
}
}
}
say @a-[@s1]-; # (0 1 2 3 4 (Any) (Any) (Any) (Any) (Any))
say @a-[@s2]-; # (0 1 2 3 4)
但我想知道我的幼稚算法是否描述了事物在幕后的计算方式!
【问题讨论】:
-
好问题@jakar - 在我看来,这也说明了 raku 设计中的思想及其包容理念。一种更具约束性的语言会“这是正确的方法,要么(i)总是在数组末尾切断切片器 - 要么 - (ii)总是迭代到切片器的末尾”。这使用“惰性”迭代来巧妙地解决无限切片器问题 - 并且 - 如果这是我们需要的,它为我们提供了一种简洁的方法来做 (i)。
标签: slice raku lazy-sequences rakudo