Perl 6 - gather/take

控制流 gather/take

gather 是一个语句或者能返回一序列值的 block 前缀。该值来自于 gather 块中的动态作用域的 take 调用。

my $a = gather {
    take 1;
    take 5;
    take 42;
}
say join ', ', @$a;          # 1, 5, 42

gather/take 能根据上下文按需(惰性地)生成值。如果你想强制惰性求值则使用 lazy 子例程或方法。绑定到一个标量或无符号的容器上也会强制惰性求值。
举个例子:

my @vals = lazy gather {
    take 1;
    say "Produced a value";
    take 2;
}
say @vals[0];
say 'between consumption of two values';
say @vals[1];

# OUTPUT:
# 1
# between consumption of two values
# Produced a value
# 2

gather/take 是动态作用域的, 所以你可以从 gather 内部所调用的 subs 或方法中调用 take:

sub weird(@elems, :$direction = 'forward') {
    my %direction = (
        forward  => sub { take $_ for @elems },
        backward => sub { take $_ for @elems.reverse },
        random   => sub { take $_ for @elems.pick(*) },
    );
    return gather %direction{$direction}();
}

say weird(<a b c>, :direction<backward> );          # (c b a)

如果值需要在调用者这边可变, 那么使用 take-rw

take-rw

sub take-rw(\item)

将给定的项返回给闭合的 gather 块, 而不用引入一个新的容器。

my @a = 1...3;
sub f(@list){ gather for @list { take-rw $_ } };
for f(@a) { $_++ };
say @a;
# OUTPUT«[2 3 4]»
    原文作者:焉知非鱼
    原文地址: https://www.jianshu.com/p/4515952fda21
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞